mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-04-18 14:42:54 +00:00
Improve: Show message "Flames restored"
This commit is contained in:
parent
c85914672e
commit
c1065772f8
19 changed files with 192 additions and 15 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
- Fix: Issue with contact requests
|
- Fix: Issue with contact requests
|
||||||
- Improve: Video compression with progress updates
|
- Improve: Video compression with progress updates
|
||||||
|
- Improve: Show message "Flames restored"
|
||||||
|
|
||||||
## 0.0.96
|
## 0.0.96
|
||||||
|
|
||||||
|
|
|
||||||
1
assets/animated_icons/birthday-cake.json
Normal file
1
assets/animated_icons/birthday-cake.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -141,20 +141,20 @@ struct PushNotification: Sendable {
|
||||||
var kind: PushKind = .reaction
|
var kind: PushKind = .reaction
|
||||||
|
|
||||||
var messageID: String {
|
var messageID: String {
|
||||||
get {return _messageID ?? String()}
|
get {_messageID ?? String()}
|
||||||
set {_messageID = newValue}
|
set {_messageID = newValue}
|
||||||
}
|
}
|
||||||
/// Returns true if `messageID` has been explicitly set.
|
/// Returns true if `messageID` has been explicitly set.
|
||||||
var hasMessageID: Bool {return self._messageID != nil}
|
var hasMessageID: Bool {self._messageID != nil}
|
||||||
/// Clears the value of `messageID`. Subsequent reads from it will return its default value.
|
/// Clears the value of `messageID`. Subsequent reads from it will return its default value.
|
||||||
mutating func clearMessageID() {self._messageID = nil}
|
mutating func clearMessageID() {self._messageID = nil}
|
||||||
|
|
||||||
var additionalContent: String {
|
var additionalContent: String {
|
||||||
get {return _additionalContent ?? String()}
|
get {_additionalContent ?? String()}
|
||||||
set {_additionalContent = newValue}
|
set {_additionalContent = newValue}
|
||||||
}
|
}
|
||||||
/// Returns true if `additionalContent` has been explicitly set.
|
/// Returns true if `additionalContent` has been explicitly set.
|
||||||
var hasAdditionalContent: Bool {return self._additionalContent != nil}
|
var hasAdditionalContent: Bool {self._additionalContent != nil}
|
||||||
/// Clears the value of `additionalContent`. Subsequent reads from it will return its default value.
|
/// Clears the value of `additionalContent`. Subsequent reads from it will return its default value.
|
||||||
mutating func clearAdditionalContent() {self._additionalContent = nil}
|
mutating func clearAdditionalContent() {self._additionalContent = nil}
|
||||||
|
|
||||||
|
|
@ -190,11 +190,11 @@ struct PushUser: Sendable {
|
||||||
var blocked: Bool = false
|
var blocked: Bool = false
|
||||||
|
|
||||||
var lastMessageID: String {
|
var lastMessageID: String {
|
||||||
get {return _lastMessageID ?? String()}
|
get {_lastMessageID ?? String()}
|
||||||
set {_lastMessageID = newValue}
|
set {_lastMessageID = newValue}
|
||||||
}
|
}
|
||||||
/// Returns true if `lastMessageID` has been explicitly set.
|
/// Returns true if `lastMessageID` has been explicitly set.
|
||||||
var hasLastMessageID: Bool {return self._lastMessageID != nil}
|
var hasLastMessageID: Bool {self._lastMessageID != nil}
|
||||||
/// Clears the value of `lastMessageID`. Subsequent reads from it will return its default value.
|
/// Clears the value of `lastMessageID`. Subsequent reads from it will return its default value.
|
||||||
mutating func clearLastMessageID() {self._lastMessageID = nil}
|
mutating func clearLastMessageID() {self._lastMessageID = nil}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import 'package:twonly/src/database/tables/contacts.table.dart';
|
||||||
import 'package:twonly/src/database/tables/groups.table.dart';
|
import 'package:twonly/src/database/tables/groups.table.dart';
|
||||||
import 'package:twonly/src/database/tables/mediafiles.table.dart';
|
import 'package:twonly/src/database/tables/mediafiles.table.dart';
|
||||||
|
|
||||||
enum MessageType { media, text, contacts }
|
enum MessageType { media, text, contacts, restoreFlameCounter }
|
||||||
|
|
||||||
@DataClassName('Message')
|
@DataClassName('Message')
|
||||||
class Messages extends Table {
|
class Messages extends Table {
|
||||||
|
|
|
||||||
|
|
@ -3033,6 +3033,12 @@ abstract class AppLocalizations {
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'Unknown contact whose identity has not yet been verified.'**
|
/// **'Unknown contact whose identity has not yet been verified.'**
|
||||||
String get verificationBadgeRedDesc;
|
String get verificationBadgeRedDesc;
|
||||||
|
|
||||||
|
/// No description provided for @chatEntryFlameRestored.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'{count} flames restored'**
|
||||||
|
String chatEntryFlameRestored(Object count);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppLocalizationsDelegate
|
class _AppLocalizationsDelegate
|
||||||
|
|
|
||||||
|
|
@ -1695,4 +1695,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get verificationBadgeRedDesc =>
|
String get verificationBadgeRedDesc =>
|
||||||
'Unbekannter Kontakt, dessen Identität bisher nicht verifiziert wurde.';
|
'Unbekannter Kontakt, dessen Identität bisher nicht verifiziert wurde.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String chatEntryFlameRestored(Object count) {
|
||||||
|
return '$count Flammen wiederhergestellt';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1683,4 +1683,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get verificationBadgeRedDesc =>
|
String get verificationBadgeRedDesc =>
|
||||||
'Unknown contact whose identity has not yet been verified.';
|
'Unknown contact whose identity has not yet been verified.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String chatEntryFlameRestored(Object count) {
|
||||||
|
return '$count flames restored';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1683,4 +1683,9 @@ class AppLocalizationsSv extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get verificationBadgeRedDesc =>
|
String get verificationBadgeRedDesc =>
|
||||||
'Unknown contact whose identity has not yet been verified.';
|
'Unknown contact whose identity has not yet been verified.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String chatEntryFlameRestored(Object count) {
|
||||||
|
return '$count flames restored';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@ message AdditionalMessageData {
|
||||||
enum Type {
|
enum Type {
|
||||||
LINK = 0;
|
LINK = 0;
|
||||||
CONTACTS = 1;
|
CONTACTS = 1;
|
||||||
|
RESTORED_FLAME_COUNTER = 2;
|
||||||
}
|
}
|
||||||
Type type = 1;
|
Type type = 1;
|
||||||
|
|
||||||
optional string link = 2;
|
optional string link = 2;
|
||||||
repeated SharedContact contacts = 3;
|
repeated SharedContact contacts = 3;
|
||||||
|
optional int64 restored_flame_counter = 4;
|
||||||
}
|
}
|
||||||
|
|
@ -106,11 +106,14 @@ class AdditionalMessageData extends $pb.GeneratedMessage {
|
||||||
AdditionalMessageData_Type? type,
|
AdditionalMessageData_Type? type,
|
||||||
$core.String? link,
|
$core.String? link,
|
||||||
$core.Iterable<SharedContact>? contacts,
|
$core.Iterable<SharedContact>? contacts,
|
||||||
|
$fixnum.Int64? restoredFlameCounter,
|
||||||
}) {
|
}) {
|
||||||
final result = create();
|
final result = create();
|
||||||
if (type != null) result.type = type;
|
if (type != null) result.type = type;
|
||||||
if (link != null) result.link = link;
|
if (link != null) result.link = link;
|
||||||
if (contacts != null) result.contacts.addAll(contacts);
|
if (contacts != null) result.contacts.addAll(contacts);
|
||||||
|
if (restoredFlameCounter != null)
|
||||||
|
result.restoredFlameCounter = restoredFlameCounter;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,6 +138,7 @@ class AdditionalMessageData extends $pb.GeneratedMessage {
|
||||||
..pc<SharedContact>(
|
..pc<SharedContact>(
|
||||||
3, _omitFieldNames ? '' : 'contacts', $pb.PbFieldType.PM,
|
3, _omitFieldNames ? '' : 'contacts', $pb.PbFieldType.PM,
|
||||||
subBuilder: SharedContact.create)
|
subBuilder: SharedContact.create)
|
||||||
|
..aInt64(4, _omitFieldNames ? '' : 'restoredFlameCounter')
|
||||||
..hasRequiredFields = false;
|
..hasRequiredFields = false;
|
||||||
|
|
||||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||||
|
|
@ -180,6 +184,15 @@ class AdditionalMessageData extends $pb.GeneratedMessage {
|
||||||
|
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
$pb.PbList<SharedContact> get contacts => $_getList(2);
|
$pb.PbList<SharedContact> get contacts => $_getList(2);
|
||||||
|
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$fixnum.Int64 get restoredFlameCounter => $_getI64(3);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
set restoredFlameCounter($fixnum.Int64 value) => $_setInt64(3, value);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.bool hasRestoredFlameCounter() => $_has(3);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
void clearRestoredFlameCounter() => $_clearField(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
const $core.bool _omitFieldNames =
|
const $core.bool _omitFieldNames =
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,19 @@ class AdditionalMessageData_Type extends $pb.ProtobufEnum {
|
||||||
AdditionalMessageData_Type._(0, _omitEnumNames ? '' : 'LINK');
|
AdditionalMessageData_Type._(0, _omitEnumNames ? '' : 'LINK');
|
||||||
static const AdditionalMessageData_Type CONTACTS =
|
static const AdditionalMessageData_Type CONTACTS =
|
||||||
AdditionalMessageData_Type._(1, _omitEnumNames ? '' : 'CONTACTS');
|
AdditionalMessageData_Type._(1, _omitEnumNames ? '' : 'CONTACTS');
|
||||||
|
static const AdditionalMessageData_Type RESTORED_FLAME_COUNTER =
|
||||||
|
AdditionalMessageData_Type._(
|
||||||
|
2, _omitEnumNames ? '' : 'RESTORED_FLAME_COUNTER');
|
||||||
|
|
||||||
static const $core.List<AdditionalMessageData_Type> values =
|
static const $core.List<AdditionalMessageData_Type> values =
|
||||||
<AdditionalMessageData_Type>[
|
<AdditionalMessageData_Type>[
|
||||||
LINK,
|
LINK,
|
||||||
CONTACTS,
|
CONTACTS,
|
||||||
|
RESTORED_FLAME_COUNTER,
|
||||||
];
|
];
|
||||||
|
|
||||||
static final $core.List<AdditionalMessageData_Type?> _byValue =
|
static final $core.List<AdditionalMessageData_Type?> _byValue =
|
||||||
$pb.ProtobufEnum.$_initByValueList(values, 1);
|
$pb.ProtobufEnum.$_initByValueList(values, 2);
|
||||||
static AdditionalMessageData_Type? valueOf($core.int value) =>
|
static AdditionalMessageData_Type? valueOf($core.int value) =>
|
||||||
value < 0 || value >= _byValue.length ? null : _byValue[value];
|
value < 0 || value >= _byValue.length ? null : _byValue[value];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,20 @@ const AdditionalMessageData$json = {
|
||||||
'6': '.SharedContact',
|
'6': '.SharedContact',
|
||||||
'10': 'contacts'
|
'10': 'contacts'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'1': 'restored_flame_counter',
|
||||||
|
'3': 4,
|
||||||
|
'4': 1,
|
||||||
|
'5': 3,
|
||||||
|
'9': 1,
|
||||||
|
'10': 'restoredFlameCounter',
|
||||||
|
'17': true
|
||||||
|
},
|
||||||
],
|
],
|
||||||
'4': [AdditionalMessageData_Type$json],
|
'4': [AdditionalMessageData_Type$json],
|
||||||
'8': [
|
'8': [
|
||||||
{'1': '_link'},
|
{'1': '_link'},
|
||||||
|
{'1': '_restored_flame_counter'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -70,6 +80,7 @@ const AdditionalMessageData_Type$json = {
|
||||||
'2': [
|
'2': [
|
||||||
{'1': 'LINK', '2': 0},
|
{'1': 'LINK', '2': 0},
|
||||||
{'1': 'CONTACTS', '2': 1},
|
{'1': 'CONTACTS', '2': 1},
|
||||||
|
{'1': 'RESTORED_FLAME_COUNTER', '2': 2},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -77,5 +88,7 @@ const AdditionalMessageData_Type$json = {
|
||||||
final $typed_data.Uint8List additionalMessageDataDescriptor = $convert.base64Decode(
|
final $typed_data.Uint8List additionalMessageDataDescriptor = $convert.base64Decode(
|
||||||
'ChVBZGRpdGlvbmFsTWVzc2FnZURhdGESLwoEdHlwZRgBIAEoDjIbLkFkZGl0aW9uYWxNZXNzYW'
|
'ChVBZGRpdGlvbmFsTWVzc2FnZURhdGESLwoEdHlwZRgBIAEoDjIbLkFkZGl0aW9uYWxNZXNzYW'
|
||||||
'dlRGF0YS5UeXBlUgR0eXBlEhcKBGxpbmsYAiABKAlIAFIEbGlua4gBARIqCghjb250YWN0cxgD'
|
'dlRGF0YS5UeXBlUgR0eXBlEhcKBGxpbmsYAiABKAlIAFIEbGlua4gBARIqCghjb250YWN0cxgD'
|
||||||
'IAMoCzIOLlNoYXJlZENvbnRhY3RSCGNvbnRhY3RzIh4KBFR5cGUSCAoETElOSxAAEgwKCENPTl'
|
'IAMoCzIOLlNoYXJlZENvbnRhY3RSCGNvbnRhY3RzEjkKFnJlc3RvcmVkX2ZsYW1lX2NvdW50ZX'
|
||||||
'RBQ1RTEAFCBwoFX2xpbms=');
|
'IYBCABKANIAVIUcmVzdG9yZWRGbGFtZUNvdW50ZXKIAQEiOgoEVHlwZRIICgRMSU5LEAASDAoI'
|
||||||
|
'Q09OVEFDVFMQARIaChZSRVNUT1JFRF9GTEFNRV9DT1VOVEVSEAJCBwoFX2xpbmtCGQoXX3Jlc3'
|
||||||
|
'RvcmVkX2ZsYW1lX2NvdW50ZXI=');
|
||||||
|
|
|
||||||
|
|
@ -303,6 +303,8 @@ Color getMessageColorFromType(
|
||||||
Color color;
|
Color color;
|
||||||
|
|
||||||
if (message.type == MessageType.text.name) {
|
if (message.type == MessageType.text.name) {
|
||||||
|
color = Colors.orange;
|
||||||
|
} else if (message.type == MessageType.text.name) {
|
||||||
color = Colors.blueAccent;
|
color = Colors.blueAccent;
|
||||||
} else if (mediaFile != null) {
|
} else if (mediaFile != null) {
|
||||||
if (mediaFile.requiresAuthentication) {
|
if (mediaFile.requiresAuthentication) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import 'package:twonly/src/services/mediafiles/mediafile.service.dart';
|
||||||
import 'package:twonly/src/views/chats/chat_messages_components/chat_reaction_row.dart';
|
import 'package:twonly/src/views/chats/chat_messages_components/chat_reaction_row.dart';
|
||||||
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_audio_entry.dart';
|
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_audio_entry.dart';
|
||||||
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_contacts.entry.dart';
|
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_contacts.entry.dart';
|
||||||
|
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_flame_restored.entry.dart';
|
||||||
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_media_entry.dart';
|
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_media_entry.dart';
|
||||||
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_text_entry.dart';
|
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_text_entry.dart';
|
||||||
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_unkown.entry.dart';
|
import 'package:twonly/src/views/chats/chat_messages_components/entries/chat_unkown.entry.dart';
|
||||||
|
|
@ -132,6 +133,12 @@ class _ChatListEntryState extends State<ChatListEntry> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (widget.message.type == MessageType.restoreFlameCounter.name) {
|
||||||
|
return ChatFlameRestoredEntry(
|
||||||
|
message: widget.message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return const ChatUnknownEntry();
|
return const ChatUnknownEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:twonly/src/database/twonly.db.dart';
|
||||||
|
import 'package:twonly/src/model/protobuf/client/generated/data.pb.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
import 'package:twonly/src/views/components/better_text.dart';
|
||||||
|
|
||||||
|
class ChatFlameRestoredEntry extends StatelessWidget {
|
||||||
|
const ChatFlameRestoredEntry({
|
||||||
|
required this.message,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Message message;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
AdditionalMessageData? data;
|
||||||
|
|
||||||
|
if (message.additionalMessageData != null) {
|
||||||
|
try {
|
||||||
|
data = AdditionalMessageData.fromBuffer(
|
||||||
|
message.additionalMessageData!,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
data = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data == null || !data.hasRestoredFlameCounter()) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxWidth: MediaQuery.of(context).size.width * 0.8,
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.only(left: 10, top: 6, bottom: 6, right: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.orange,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: BetterText(
|
||||||
|
text: context.lang
|
||||||
|
.chatEntryFlameRestored(data.restoredFlameCounter.toInt()),
|
||||||
|
textColor: isDarkMode(context) ? Colors.black : Colors.black,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -113,6 +113,7 @@ class EmojiAnimation extends StatelessWidget {
|
||||||
'💯': '100.lottie',
|
'💯': '100.lottie',
|
||||||
'🎉': 'party-popper.lottie',
|
'🎉': 'party-popper.lottie',
|
||||||
'🎊': 'confetti-ball.lottie',
|
'🎊': 'confetti-ball.lottie',
|
||||||
|
'🎂': 'birthday-cake.json',
|
||||||
'🧡': 'orange-heart.lottie',
|
'🧡': 'orange-heart.lottie',
|
||||||
'💛': 'yellow-heart.lottie',
|
'💛': 'yellow-heart.lottie',
|
||||||
'💚': 'green-heart.lottie',
|
'💚': 'green-heart.lottie',
|
||||||
|
|
|
||||||
|
|
@ -82,10 +82,11 @@ class _FlameCounterWidgetState extends State<FlameCounterWidget> {
|
||||||
if (widget.prefix) const SizedBox(width: 5),
|
if (widget.prefix) const SizedBox(width: 5),
|
||||||
if (widget.prefix) const Text('•'),
|
if (widget.prefix) const Text('•'),
|
||||||
if (widget.prefix) const SizedBox(width: 5),
|
if (widget.prefix) const SizedBox(width: 5),
|
||||||
Text(
|
if (flameCounter != 100)
|
||||||
flameCounter.toString(),
|
Text(
|
||||||
style: const TextStyle(fontSize: 13),
|
flameCounter.toString(),
|
||||||
),
|
style: const TextStyle(fontSize: 13),
|
||||||
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 15,
|
height: 15,
|
||||||
child: EmojiAnimation(
|
child: EmojiAnimation(
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:clock/clock.dart';
|
import 'package:clock/clock.dart';
|
||||||
import 'package:drift/drift.dart' show Value;
|
import 'package:drift/drift.dart' show Value;
|
||||||
|
import 'package:fixnum/fixnum.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/constants/routes.keys.dart';
|
import 'package:twonly/src/constants/routes.keys.dart';
|
||||||
|
import 'package:twonly/src/database/tables/messages.table.dart';
|
||||||
import 'package:twonly/src/database/twonly.db.dart';
|
import 'package:twonly/src/database/twonly.db.dart';
|
||||||
|
import 'package:twonly/src/model/protobuf/client/generated/data.pb.dart';
|
||||||
|
import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart'
|
||||||
|
as pb;
|
||||||
|
import 'package:twonly/src/services/api/messages.dart';
|
||||||
import 'package:twonly/src/services/flame.service.dart';
|
import 'package:twonly/src/services/flame.service.dart';
|
||||||
import 'package:twonly/src/services/subscription.service.dart';
|
import 'package:twonly/src/services/subscription.service.dart';
|
||||||
import 'package:twonly/src/utils/log.dart';
|
import 'package:twonly/src/utils/log.dart';
|
||||||
|
|
@ -46,7 +53,8 @@ class _MaxFlameListTitleState extends State<MaxFlameListTitle> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _restoreFlames() async {
|
Future<void> _restoreFlames() async {
|
||||||
if (!isUserAllowed(getCurrentPlan(), PremiumFeatures.RestoreFlames)) {
|
if (!isUserAllowed(getCurrentPlan(), PremiumFeatures.RestoreFlames) &&
|
||||||
|
kReleaseMode) {
|
||||||
await context.push(Routes.settingsSubscription);
|
await context.push(Routes.settingsSubscription);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +68,40 @@ class _MaxFlameListTitleState extends State<MaxFlameListTitle> {
|
||||||
lastFlameCounterChange: Value(clock.now()),
|
lastFlameCounterChange: Value(clock.now()),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final addData = AdditionalMessageData(
|
||||||
|
type: AdditionalMessageData_Type.RESTORED_FLAME_COUNTER,
|
||||||
|
restoredFlameCounter: Int64(_group!.maxFlameCounter),
|
||||||
|
);
|
||||||
|
|
||||||
|
final message = await twonlyDB.messagesDao.insertMessage(
|
||||||
|
MessagesCompanion(
|
||||||
|
groupId: Value(_groupId),
|
||||||
|
type: Value(MessageType.restoreFlameCounter.name),
|
||||||
|
additionalMessageData: Value(addData.writeToBuffer()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (message == null) {
|
||||||
|
Log.error('Could not insert message into database');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final encryptedContent = pb.EncryptedContent(
|
||||||
|
additionalDataMessage: pb.EncryptedContent_AdditionalDataMessage(
|
||||||
|
senderMessageId: message.messageId,
|
||||||
|
additionalMessageData: addData.writeToBuffer(),
|
||||||
|
timestamp: Int64(message.createdAt.millisecondsSinceEpoch),
|
||||||
|
type: MessageType.restoreFlameCounter.name,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
await syncFlameCounters(forceForGroup: _groupId);
|
await syncFlameCounters(forceForGroup: _groupId);
|
||||||
|
await sendCipherTextToGroup(
|
||||||
|
_groupId,
|
||||||
|
encryptedContent,
|
||||||
|
messageId: message.messageId,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:clock/clock.dart';
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:restart_app/restart_app.dart';
|
import 'package:restart_app/restart_app.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/constants/routes.keys.dart';
|
import 'package:twonly/src/constants/routes.keys.dart';
|
||||||
|
import 'package:twonly/src/database/twonly.db.dart';
|
||||||
import 'package:twonly/src/utils/storage.dart';
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||||
|
|
||||||
|
|
@ -67,6 +70,24 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
if (!kReleaseMode)
|
||||||
|
ListTile(
|
||||||
|
title: const Text('Make it possible to reset flames'),
|
||||||
|
onTap: () async {
|
||||||
|
final chats = await twonlyDB.groupsDao.getAllDirectChats();
|
||||||
|
|
||||||
|
for (final chat in chats) {
|
||||||
|
await twonlyDB.groupsDao.updateGroup(
|
||||||
|
chat.groupId,
|
||||||
|
GroupsCompanion(
|
||||||
|
flameCounter: const Value(0),
|
||||||
|
maxFlameCounter: const Value(365),
|
||||||
|
lastFlameCounterChange: Value(clock.now()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
if (!kReleaseMode)
|
if (!kReleaseMode)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Automated Testing'),
|
title: const Text('Automated Testing'),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue