diff --git a/android/app/build.gradle b/android/app/build.gradle
index a500868..bb0c654 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -55,6 +55,9 @@ android {
debug {
applicationIdSuffix ".testing"
}
+ // profile {
+ // applicationIdSuffix ".STOP"
+ // }
release {
signingConfig signingConfigs.release
}
diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml
index e807f77..8606e90 100644
--- a/android/app/src/profile/AndroidManifest.xml
+++ b/android/app/src/profile/AndroidManifest.xml
@@ -6,4 +6,6 @@
+
+
diff --git a/lib/main.dart b/lib/main.dart
index 61644cd..6b80c64 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -21,6 +21,7 @@ import 'package:twonly/src/services/api/mediafiles/upload.service.dart';
import 'package:twonly/src/services/fcm.service.dart';
import 'package:twonly/src/services/mediafiles/mediafile.service.dart';
import 'package:twonly/src/services/notifications/setup.notifications.dart';
+import 'package:twonly/src/services/twonly_safe/create_backup.twonly_safe.dart';
import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/storage.dart';
@@ -63,13 +64,7 @@ void main() async {
unawaited(createPushAvatars());
await twonlyDB.messagesDao.purgeMessageTable();
- // await twonlyDB.messagesDao.resetPendingDownloadState();
- // await twonlyDB.messageRetransmissionDao.purgeOldRetransmissions();
- // await twonlyDB.signalDao.purgeOutDatedPreKeys();
-
- // unawaited(purgeSendMediaFiles());
-
- // unawaited(performTwonlySafeBackup());
+ unawaited(performTwonlySafeBackup());
runApp(
MultiProvider(
diff --git a/lib/src/database/daos/contacts.dao.dart b/lib/src/database/daos/contacts.dao.dart
index 7435688..0d4b6a8 100644
--- a/lib/src/database/daos/contacts.dao.dart
+++ b/lib/src/database/daos/contacts.dao.dart
@@ -109,6 +109,7 @@ class ContactsDao extends DatabaseAccessor with _$ContactsDaoMixin {
..where(
contacts.requested.equals(true) &
contacts.accepted.equals(false) &
+ contacts.deletedByUser.equals(false) &
contacts.blocked.equals(false),
)
..addColumns([count]);
diff --git a/lib/src/database/daos/groups.dao.dart b/lib/src/database/daos/groups.dao.dart
index 0dd04e8..85ce7ec 100644
--- a/lib/src/database/daos/groups.dao.dart
+++ b/lib/src/database/daos/groups.dao.dart
@@ -281,7 +281,7 @@ class GroupsDao extends DatabaseAccessor with _$GroupsDaoMixin {
..where((t) => t.groupId.equals(groupId)))
.getSingle();
- final totalMediaCounter = group.totalMediaCounter + 1;
+ final totalMediaCounter = group.totalMediaCounter + (received ? 0 : 1);
var flameCounter = group.flameCounter;
var maxFlameCounter = group.maxFlameCounter;
var maxFlameCounterFrom = group.maxFlameCounterFrom;
@@ -321,7 +321,11 @@ class GroupsDao extends DatabaseAccessor with _$GroupsDaoMixin {
if (updateFlame) {
flameCounter += 1;
lastFlameCounterChange = Value(timestamp);
- if ((flameCounter + 1) >= maxFlameCounter) {
+ // Overwrite max flame counter either the current is bigger or the th max flame counter is older then 4 days
+ if ((flameCounter + 1) >= maxFlameCounter ||
+ maxFlameCounterFrom == null ||
+ maxFlameCounterFrom
+ .isBefore(DateTime.now().subtract(const Duration(days: 5)))) {
maxFlameCounter = flameCounter + 1;
maxFlameCounterFrom = DateTime.now();
}
@@ -351,6 +355,15 @@ class GroupsDao extends DatabaseAccessor with _$GroupsDaoMixin {
);
}
+ Stream watchSumTotalMediaCounter() {
+ final query = selectOnly(groups)
+ ..addColumns([groups.totalMediaCounter.sum()]);
+ return query.watch().map((rows) {
+ final expr = rows.first.read(groups.totalMediaCounter.sum());
+ return expr ?? 0;
+ });
+ }
+
Future increaseLastMessageExchange(
String groupId,
DateTime newLastMessage,
diff --git a/lib/src/localization/app_de.arb b/lib/src/localization/app_de.arb
index f14986a..85299bc 100644
--- a/lib/src/localization/app_de.arb
+++ b/lib/src/localization/app_de.arb
@@ -816,5 +816,6 @@
"deleteChatAfterADay": "einem Tag.",
"deleteChatAfterAWeek": "einer Woche.",
"deleteChatAfterAMonth": "einem Monat.",
- "deleteChatAfterAYear": "einem Jahr."
+ "deleteChatAfterAYear": "einem Jahr.",
+ "yourTwonlyScore": "Dein twonly-Score"
}
\ No newline at end of file
diff --git a/lib/src/localization/app_en.arb b/lib/src/localization/app_en.arb
index 08f553c..4078005 100644
--- a/lib/src/localization/app_en.arb
+++ b/lib/src/localization/app_en.arb
@@ -594,5 +594,6 @@
"deleteChatAfterADay": "one day.",
"deleteChatAfterAWeek": "one week.",
"deleteChatAfterAMonth": "one month.",
- "deleteChatAfterAYear": "one year."
+ "deleteChatAfterAYear": "one year.",
+ "yourTwonlyScore": "Your twonly-Score"
}
\ No newline at end of file
diff --git a/lib/src/localization/generated/app_localizations.dart b/lib/src/localization/generated/app_localizations.dart
index 140bc39..db8ac2b 100644
--- a/lib/src/localization/generated/app_localizations.dart
+++ b/lib/src/localization/generated/app_localizations.dart
@@ -2671,6 +2671,12 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'one year.'**
String get deleteChatAfterAYear;
+
+ /// No description provided for @yourTwonlyScore.
+ ///
+ /// In en, this message translates to:
+ /// **'Your twonly-Score'**
+ String get yourTwonlyScore;
}
class _AppLocalizationsDelegate
diff --git a/lib/src/localization/generated/app_localizations_de.dart b/lib/src/localization/generated/app_localizations_de.dart
index 2d8c516..ebe795b 100644
--- a/lib/src/localization/generated/app_localizations_de.dart
+++ b/lib/src/localization/generated/app_localizations_de.dart
@@ -1474,4 +1474,7 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get deleteChatAfterAYear => 'einem Jahr.';
+
+ @override
+ String get yourTwonlyScore => 'Dein twonly-Score';
}
diff --git a/lib/src/localization/generated/app_localizations_en.dart b/lib/src/localization/generated/app_localizations_en.dart
index 9834524..607bc3f 100644
--- a/lib/src/localization/generated/app_localizations_en.dart
+++ b/lib/src/localization/generated/app_localizations_en.dart
@@ -1464,4 +1464,7 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get deleteChatAfterAYear => 'one year.';
+
+ @override
+ String get yourTwonlyScore => 'Your twonly-Score';
}
diff --git a/lib/src/services/api.service.dart b/lib/src/services/api.service.dart
index a918d29..4cc3e23 100644
--- a/lib/src/services/api.service.dart
+++ b/lib/src/services/api.service.dart
@@ -51,8 +51,8 @@ final lockRetransStore = Mutex();
/// errors or network changes.
class ApiService {
ApiService();
- final String apiHost = kDebugMode ? '10.99.0.140:3030' : 'api.twonly.eu';
- final String apiSecure = kDebugMode ? '' : 's';
+ final String apiHost = kReleaseMode ? 'api.twonly.eu' : '10.99.0.140:3030';
+ final String apiSecure = kReleaseMode ? 's' : '';
bool appIsOutdated = false;
bool isAuthenticated = false;
diff --git a/lib/src/services/api/mediafiles/media_background.service.dart b/lib/src/services/api/mediafiles/media_background.service.dart
index 8d1283e..6e513d2 100644
--- a/lib/src/services/api/mediafiles/media_background.service.dart
+++ b/lib/src/services/api/mediafiles/media_background.service.dart
@@ -35,15 +35,15 @@ Future initFileDownloader() async {
try {
var androidConfig = [];
- if (kDebugMode) {
- androidConfig = [(Config.bypassTLSCertificateValidation, kDebugMode)];
+ if (!kReleaseMode) {
+ androidConfig = [(Config.bypassTLSCertificateValidation, true)];
}
await FileDownloader().configure(androidConfig: androidConfig);
} catch (e) {
Log.error(e);
}
- if (kDebugMode) {
+ if (!kReleaseMode) {
FileDownloader().configureNotification(
running: const TaskNotification(
'Uploading/Downloading',
diff --git a/lib/src/services/notifications/background.notifications.dart b/lib/src/services/notifications/background.notifications.dart
index ac5a889..905c3ed 100644
--- a/lib/src/services/notifications/background.notifications.dart
+++ b/lib/src/services/notifications/background.notifications.dart
@@ -23,9 +23,10 @@ Future customLocalPushNotification(String title, String msg) async {
'1',
'System',
channelDescription: 'System messages.',
- importance: Importance.max,
- priority: Priority.max,
+ importance: Importance.high,
+ priority: Priority.high,
styleInformation: BigTextStyleInformation(msg),
+ icon: 'ic_launcher_foreground',
);
const darwinNotificationDetails = DarwinNotificationDetails();
@@ -34,8 +35,10 @@ Future customLocalPushNotification(String title, String msg) async {
iOS: darwinNotificationDetails,
);
+ final id = Random.secure().nextInt(9999);
+
await flutterLocalNotificationsPlugin.show(
- Random.secure().nextInt(9999),
+ id,
title,
msg,
notificationDetails,
@@ -95,11 +98,11 @@ Future handlePushData(String pushDataB64) async {
}
}
} catch (e) {
+ Log.error(e);
await customLocalPushNotification(
'Du hast eine neue Nachricht.',
'Öffne twonly um mehr zu erfahren.',
);
- Log.error(e);
}
}
@@ -161,6 +164,7 @@ Future showLocalPushNotification(
priority: Priority.max,
ticker: 'You got a new message.',
largeIcon: styleInformation,
+ icon: 'ic_launcher_foreground',
);
const darwinNotificationDetails = DarwinNotificationDetails();
@@ -174,7 +178,7 @@ Future showLocalPushNotification(
title,
body,
notificationDetails,
- payload: pushNotification.kind.name,
+ // payload: pushNotification.kind.name,
);
}
diff --git a/lib/src/services/notifications/pushkeys.notifications.dart b/lib/src/services/notifications/pushkeys.notifications.dart
index 64509a8..b02ab0f 100644
--- a/lib/src/services/notifications/pushkeys.notifications.dart
+++ b/lib/src/services/notifications/pushkeys.notifications.dart
@@ -51,7 +51,7 @@ Future setupNotificationWithUsers({
final pushUser =
pushUsers.firstWhereOrNull((x) => x.userId == contact.userId);
- if (pushUser != null) {
+ if (pushUser != null && pushUser.pushKeys.isNotEmpty) {
// make it harder to predict the change of the key
final timeBefore =
DateTime.now().subtract(Duration(days: 5 + random.nextInt(5)));
diff --git a/lib/src/utils/log.dart b/lib/src/utils/log.dart
index 8917f23..0344dfa 100644
--- a/lib/src/utils/log.dart
+++ b/lib/src/utils/log.dart
@@ -9,7 +9,7 @@ void initLogger() {
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((record) async {
await _writeLogToFile(record);
- if (kDebugMode) {
+ if (!kReleaseMode) {
print(
'${record.level.name} [twonly] ${record.loggerName} > ${record.message}',
);
diff --git a/lib/src/utils/misc.dart b/lib/src/utils/misc.dart
index c41c306..27b151e 100644
--- a/lib/src/utils/misc.dart
+++ b/lib/src/utils/misc.dart
@@ -263,7 +263,7 @@ bool isUUIDNewer(String uuid1, String uuid2) {
return timestamp1 > timestamp2;
} catch (e) {
Log.error(e);
- return true;
+ return false;
}
}
diff --git a/lib/src/views/camera/camera_preview_components/zoom_selector.dart b/lib/src/views/camera/camera_preview_components/zoom_selector.dart
index 3d4f944..856224e 100644
--- a/lib/src/views/camera/camera_preview_components/zoom_selector.dart
+++ b/lib/src/views/camera/camera_preview_components/zoom_selector.dart
@@ -3,10 +3,10 @@
import 'dart:async';
import 'dart:io';
import 'dart:math';
-
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:twonly/globals.dart';
+import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/views/camera/camera_preview_controller_view.dart';
class CameraZoomButtons extends StatefulWidget {
@@ -50,6 +50,7 @@ class _CameraZoomButtonsState extends State {
Future initAsync() async {
showWideAngleZoom = (await widget.controller.getMinZoomLevel()) < 1;
+ Log.info('Found ${gCameras.length} cameras for zoom.');
if (!showWideAngleZoom && Platform.isIOS && gCameras.length == 3) {
showWideAngleZoomIOS = true;
}
diff --git a/lib/src/views/camera/image_editor/layers/filters/location_filter.dart b/lib/src/views/camera/image_editor/layers/filters/location_filter.dart
index 5b3ae64..d8ef27f 100644
--- a/lib/src/views/camera/image_editor/layers/filters/location_filter.dart
+++ b/lib/src/views/camera/image_editor/layers/filters/location_filter.dart
@@ -131,7 +131,7 @@ Future> getStickerIndex() async {
final indexFile = File('${directory.path}/stickers.json');
var res = [];
- if (indexFile.existsSync() && !kDebugMode) {
+ if (indexFile.existsSync() && kReleaseMode) {
final lastModified = indexFile.lastModifiedSync();
final difference = DateTime.now().difference(lastModified);
final content = await indexFile.readAsString();
diff --git a/lib/src/views/chats/chat_messages_components/chat_reaction_row.dart b/lib/src/views/chats/chat_messages_components/chat_reaction_row.dart
index c6d4a27..1a46d10 100644
--- a/lib/src/views/chats/chat_messages_components/chat_reaction_row.dart
+++ b/lib/src/views/chats/chat_messages_components/chat_reaction_row.dart
@@ -1,3 +1,5 @@
+import 'dart:io';
+
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
@@ -45,10 +47,10 @@ class ReactionRow extends StatelessWidget {
child: Center(
child: Text(
reaction.emoji,
- style: const TextStyle(fontSize: 18),
- strutStyle: const StrutStyle(
+ style: TextStyle(fontSize: Platform.isIOS ? 18 : 15),
+ strutStyle: StrutStyle(
forceStrutHeight: true,
- height: 1.6,
+ height: Platform.isIOS ? 1.6 : 1.3,
),
),
),
@@ -114,7 +116,7 @@ class ReactionRow extends StatelessWidget {
entry.$2.toString(),
textAlign: TextAlign.center,
style: TextStyle(
- fontSize: 15,
+ fontSize: 13,
color:
isDarkMode(context) ? Colors.white : Colors.black,
decoration: TextDecoration.none,
diff --git a/lib/src/views/chats/chat_messages_components/entries/chat_media_entry.dart b/lib/src/views/chats/chat_messages_components/entries/chat_media_entry.dart
index 96104b4..1f89085 100644
--- a/lib/src/views/chats/chat_messages_components/entries/chat_media_entry.dart
+++ b/lib/src/views/chats/chat_messages_components/entries/chat_media_entry.dart
@@ -67,9 +67,10 @@ class _ChatMediaEntryState extends State {
if (widget.message.openedAt == null || widget.message.mediaStored) {
return;
}
- if (widget.mediaService.tempPath.existsSync()) {
- await sendCipherTextToGroup(
- widget.message.groupId,
+ if (widget.mediaService.tempPath.existsSync() &&
+ widget.message.senderId != null) {
+ await sendCipherText(
+ widget.message.senderId!,
EncryptedContent(
mediaUpdate: EncryptedContent_MediaUpdate(
type: EncryptedContent_MediaUpdate_Type.REOPENED,
diff --git a/lib/src/views/chats/chat_messages_components/entries/chat_text_entry.dart b/lib/src/views/chats/chat_messages_components/entries/chat_text_entry.dart
index 89c336e..0d9f365 100644
--- a/lib/src/views/chats/chat_messages_components/entries/chat_text_entry.dart
+++ b/lib/src/views/chats/chat_messages_components/entries/chat_text_entry.dart
@@ -77,10 +77,10 @@ class ChatTextEntry extends StatelessWidget {
children: [
if (info.expanded)
Expanded(
- child: BetterText(text: text, textColor: info.textColor),
+ child: BetterText(text: info.text, textColor: info.textColor),
)
else ...[
- BetterText(text: text, textColor: info.textColor),
+ BetterText(text: info.text, textColor: info.textColor),
SizedBox(
width: info.spacerWidth,
),
diff --git a/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart b/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart
index e147dbc..9f2aefc 100644
--- a/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart
+++ b/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart
@@ -242,10 +242,10 @@ class _MessageSendStateIconState extends State {
child: Center(
child: Text(
widget.lastReaction!.emoji,
- style: const TextStyle(fontSize: 18),
+ style: const TextStyle(fontSize: 15),
strutStyle: const StrutStyle(
forceStrutHeight: true,
- height: 1.6,
+ height: 1.4,
),
),
),
diff --git a/lib/src/views/chats/chat_messages_components/test b/lib/src/views/chats/chat_messages_components/test
deleted file mode 100644
index db5158b..0000000
--- a/lib/src/views/chats/chat_messages_components/test
+++ /dev/null
@@ -1,242 +0,0 @@
-import 'dart:io';
-
-import 'package:audio_waveforms/audio_waveforms.dart';
-import 'package:audio_waveforms_example/chat_bubble.dart';
-import 'package:file_picker/file_picker.dart';
-import 'package:flutter/material.dart';
-import 'package:path_provider/path_provider.dart';
-
-void main() => runApp(const MyApp());
-
-class MyApp extends StatelessWidget {
- const MyApp({super.key});
-
- @override
- Widget build(BuildContext context) {
- return const MaterialApp(
- title: 'Audio Waveforms',
- debugShowCheckedModeBanner: false,
- home: Home(),
- );
- }
-}
-
-class Home extends StatefulWidget {
- const Home({super.key});
-
- @override
- State createState() => _HomeState();
-}
-
-class _HomeState extends State {
- late final RecorderController recorderController;
-
- String? path;
- String? musicFile;
- bool isRecording = false;
- bool isRecordingCompleted = false;
- bool isLoading = true;
- late Directory appDirectory;
-
- @override
- void initState() {
- super.initState();
- _getDir();
- _initialiseControllers();
- }
-
- void _getDir() async {
- appDirectory = await getApplicationDocumentsDirectory();
- path = "${appDirectory.path}/recording.m4a";
- isLoading = false;
- setState(() {});
- }
-
- void _initialiseControllers() {
- recorderController = RecorderController()
- ..androidEncoder = AndroidEncoder.aac
- ..androidOutputFormat = AndroidOutputFormat.mpeg4
- ..iosEncoder = IosEncoder.kAudioFormatMPEG4AAC
- ..sampleRate = 44100;
- }
-
- void _pickFile() async {
- FilePickerResult? result = await FilePicker.platform.pickFiles();
- if (result != null) {
- musicFile = result.files.single.path;
- setState(() {});
- } else {
- debugPrint("File not picked");
- }
- }
-
- @override
- void dispose() {
- recorderController.dispose();
- super.dispose();
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- backgroundColor: const Color(0xFF252331),
- appBar: AppBar(
- backgroundColor: const Color(0xFF252331),
- elevation: 1,
- centerTitle: true,
- shadowColor: Colors.grey,
- title: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Image.asset(
- 'assets/images/logo.png',
- scale: 1.5,
- ),
- const SizedBox(width: 10),
- const Text(
- 'Simform',
- style: TextStyle(color: Colors.white),
- ),
- ],
- ),
- ),
- body: isLoading
- ? const Center(
- child: CircularProgressIndicator(),
- )
- : SafeArea(
- child: Column(
- children: [
- const SizedBox(height: 20),
- Expanded(
- child: ListView.builder(
- itemCount: 4,
- itemBuilder: (_, index) {
- return WaveBubble(
- index: index + 1,
- isSender: index.isOdd,
- width: MediaQuery.of(context).size.width / 2,
- appDirectory: appDirectory,
- );
- },
- ),
- ),
- if (isRecordingCompleted)
- WaveBubble(
- path: path,
- isSender: true,
- appDirectory: appDirectory,
- ),
- if (musicFile != null)
- WaveBubble(
- path: musicFile,
- isSender: true,
- appDirectory: appDirectory,
- ),
- SafeArea(
- child: Row(
- children: [
- AnimatedSwitcher(
- duration: const Duration(milliseconds: 200),
- child: isRecording
- ? AudioWaveforms(
- enableGesture: true,
- size: Size(
- MediaQuery.of(context).size.width / 2,
- 50),
- recorderController: recorderController,
- waveStyle: const WaveStyle(
- waveColor: Colors.white,
- extendWaveform: true,
- showMiddleLine: false,
- ),
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(12.0),
- color: const Color(0xFF1E1B26),
- ),
- padding: const EdgeInsets.only(left: 18),
- margin: const EdgeInsets.symmetric(
- horizontal: 15),
- )
- : Container(
- width:
- MediaQuery.of(context).size.width / 1.7,
- height: 50,
- decoration: BoxDecoration(
- color: const Color(0xFF1E1B26),
- borderRadius: BorderRadius.circular(12.0),
- ),
- padding: const EdgeInsets.only(left: 18),
- margin: const EdgeInsets.symmetric(
- horizontal: 15),
- child: TextField(
- readOnly: true,
- decoration: InputDecoration(
- hintText: "Type Something...",
- hintStyle: const TextStyle(
- color: Colors.white54),
- contentPadding:
- const EdgeInsets.only(top: 16),
- border: InputBorder.none,
- suffixIcon: IconButton(
- onPressed: _pickFile,
- icon: Icon(Icons.adaptive.share),
- color: Colors.white54,
- ),
- ),
- ),
- ),
- ),
- IconButton(
- onPressed: _refreshWave,
- icon: Icon(
- isRecording ? Icons.refresh : Icons.send,
- color: Colors.white,
- ),
- ),
- const SizedBox(width: 16),
- IconButton(
- onPressed: _startOrStopRecording,
- icon: Icon(isRecording ? Icons.stop : Icons.mic),
- color: Colors.white,
- iconSize: 28,
- ),
- ],
- ),
- ),
- ],
- ),
- ),
- );
- }
-
- void _startOrStopRecording() async {
- try {
- if (isRecording) {
- recorderController.reset();
-
- path = await recorderController.stop(false);
-
- if (path != null) {
- isRecordingCompleted = true;
- debugPrint(path);
- debugPrint("Recorded file size: ${File(path!).lengthSync()}");
- }
- } else {
- await recorderController.record(path: path); // Path is optional
- }
- } catch (e) {
- debugPrint(e.toString());
- } finally {
- if (recorderController.hasPermission) {
- setState(() {
- isRecording = !isRecording;
- });
- }
- }
- }
-
- void _refreshWave() {
- if (isRecording) recorderController.refresh();
- }
-}
\ No newline at end of file
diff --git a/lib/src/views/chats/media_viewer.view.dart b/lib/src/views/chats/media_viewer.view.dart
index e81347c..9fe19f9 100644
--- a/lib/src/views/chats/media_viewer.view.dart
+++ b/lib/src/views/chats/media_viewer.view.dart
@@ -82,6 +82,7 @@ class _MediaViewerViewState extends State {
_subscription.cancel();
downloadStateListener?.cancel();
videoController?.dispose();
+ videoController = null;
super.dispose();
}
@@ -141,7 +142,9 @@ class _MediaViewerViewState extends State {
Future loadCurrentMediaFile({bool showTwonly = false}) async {
if (!mounted || !context.mounted) return;
- if (allMediaFiles.isEmpty) return nextMediaOrExit();
+ if (allMediaFiles.isEmpty || allMediaFiles.first.mediaId == null) {
+ return nextMediaOrExit();
+ }
await _noScreenshot.screenshotOff();
setState(() {
@@ -175,7 +178,8 @@ class _MediaViewerViewState extends State {
downloadTriggered = true;
final mediaFile = await twonlyDB.mediaFilesDao
.getMediaFileById(allMediaFiles.first.mediaId!);
- await startDownloadMedia(mediaFile!, true);
+ if (mediaFile == null) return;
+ await startDownloadMedia(mediaFile, true);
unawaited(tryDownloadAllMediaFiles(force: true));
}
return;
@@ -269,6 +273,10 @@ class _MediaViewerViewState extends State {
}
});
progressTimer = Timer.periodic(const Duration(milliseconds: 10), (timer) {
+ if (currentMedia!.mediaFile.displayLimitInMilliseconds == null ||
+ canBeSeenUntil == null) {
+ return;
+ }
final difference = canBeSeenUntil!.difference(DateTime.now());
// Calculate the progress as a value between 0.0 and 1.0
progress = difference.inMilliseconds /
@@ -312,10 +320,12 @@ class _MediaViewerViewState extends State {
void displayShortReactions() {
final renderBox =
- mediaWidgetKey.currentContext!.findRenderObject()! as RenderBox;
+ mediaWidgetKey.currentContext!.findRenderObject() as RenderBox?;
setState(() {
showShortReactions = true;
- mediaViewerDistanceFromBottom = renderBox.size.height;
+ if (renderBox != null) {
+ mediaViewerDistanceFromBottom = renderBox.size.height;
+ }
});
}
diff --git a/lib/src/views/components/max_flame_list_title.dart b/lib/src/views/components/max_flame_list_title.dart
index ee193e7..efe80ba 100644
--- a/lib/src/views/components/max_flame_list_title.dart
+++ b/lib/src/views/components/max_flame_list_title.dart
@@ -85,7 +85,7 @@ class _MaxFlameListTitleState extends State {
if (_directChat == null ||
_directChat!.maxFlameCounter == 0 ||
_flameCounter >= (_directChat!.maxFlameCounter + 1) ||
- _directChat!.lastFlameCounterChange!
+ _directChat!.maxFlameCounterFrom!
.isBefore(DateTime.now().subtract(const Duration(days: 4)))) {
return Container();
}
diff --git a/lib/src/views/settings/account.view.dart b/lib/src/views/settings/account.view.dart
index 37af702..d56e734 100644
--- a/lib/src/views/settings/account.view.dart
+++ b/lib/src/views/settings/account.view.dart
@@ -37,7 +37,7 @@ class _AccountViewState extends State {
.where(
(x) =>
x.transactionType != Response_TransactionTypes.ThanksForTesting ||
- kDebugMode,
+ !kReleaseMode,
)
.map((a) => a.depositCents.toInt())
.sum;
@@ -101,7 +101,7 @@ class _AccountViewState extends State {
),
)
: Text(context.lang.settingsAccountDeleteAccountNoBallance),
- onLongPress: kDebugMode
+ onLongPress: !kReleaseMode
? () async {
await deleteLocalUserData();
await Restart.restartApp(
diff --git a/lib/src/views/settings/backup/twonly_safe_backup.view.dart b/lib/src/views/settings/backup/twonly_safe_backup.view.dart
index 64f7ba1..c5255d1 100644
--- a/lib/src/views/settings/backup/twonly_safe_backup.view.dart
+++ b/lib/src/views/settings/backup/twonly_safe_backup.view.dart
@@ -204,7 +204,7 @@ class _TwonlyIdentityBackupViewState extends State {
onPressed: (!isLoading &&
(passwordCtrl.text == repeatedPasswordCtrl.text &&
passwordCtrl.text.length >= 8 ||
- kDebugMode))
+ !kReleaseMode))
? onPressedEnableTwonlySafe
: null,
icon: isLoading
diff --git a/lib/src/views/settings/developer/automated_testing.view.dart b/lib/src/views/settings/developer/automated_testing.view.dart
index 89f3774..02a7b9d 100644
--- a/lib/src/views/settings/developer/automated_testing.view.dart
+++ b/lib/src/views/settings/developer/automated_testing.view.dart
@@ -32,7 +32,7 @@ class _AutomatedTestingViewState extends State {
),
body: ListView(
children: [
- if (kDebugMode)
+ if (!kReleaseMode)
ListTile(
title: const Text('Sending a lot of messages.'),
subtitle: Text(lotsOfMessagesStatus),
diff --git a/lib/src/views/settings/developer/developer.view.dart b/lib/src/views/settings/developer/developer.view.dart
index efa8812..42e4aa3 100644
--- a/lib/src/views/settings/developer/developer.view.dart
+++ b/lib/src/views/settings/developer/developer.view.dart
@@ -66,7 +66,7 @@ class _DeveloperSettingsViewState extends State {
);
},
),
- // if (kDebugMode)
+ // if (!kReleaseMode)
// ListTile(
// title: const Text('FlameSync Test'),
// onTap: () async {
@@ -74,7 +74,7 @@ class _DeveloperSettingsViewState extends State {
// await syncFlameCounters();
// },
// ),
- if (kDebugMode)
+ if (!kReleaseMode)
ListTile(
title: const Text('Automated Testing'),
onTap: () async {
diff --git a/lib/src/views/settings/profile/profile.view.dart b/lib/src/views/settings/profile/profile.view.dart
index 02aa643..5d24f45 100644
--- a/lib/src/views/settings/profile/profile.view.dart
+++ b/lib/src/views/settings/profile/profile.view.dart
@@ -25,11 +25,26 @@ class _ProfileViewState extends State {
final AvatarMakerController _avatarMakerController =
PersistentAvatarMakerController(customizedPropertyCategories: []);
+ int twonlyScore = 0;
+ late StreamSubscription twonlyScoreSub;
+
@override
void initState() {
+ twonlyScoreSub =
+ twonlyDB.groupsDao.watchSumTotalMediaCounter().listen((update) {
+ setState(() {
+ twonlyScore = update;
+ });
+ });
super.initState();
}
+ @override
+ void dispose() {
+ twonlyScoreSub.cancel();
+ super.dispose();
+ }
+
Future updateUserDisplayName(String displayName) async {
await updateUserdata((user) {
user
@@ -156,6 +171,17 @@ class _ProfileViewState extends State {
}
},
),
+ BetterListTile(
+ text: context.lang.yourTwonlyScore,
+ icon: FontAwesomeIcons.trophy,
+ trailing: Text(
+ twonlyScore.toString(),
+ style: TextStyle(
+ color: context.color.primary,
+ fontSize: 18,
+ ),
+ ),
+ ),
],
),
);
diff --git a/lib/src/views/settings/subscription/checkout.view.dart b/lib/src/views/settings/subscription/checkout.view.dart
index 83804a5..3d6797c 100644
--- a/lib/src/views/settings/subscription/checkout.view.dart
+++ b/lib/src/views/settings/subscription/checkout.view.dart
@@ -102,6 +102,7 @@ class _CheckoutViewState extends State {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Card(
+ color: context.color.surfaceContainer,
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
diff --git a/lib/src/views/settings/subscription/select_payment.view.dart b/lib/src/views/settings/subscription/select_payment.view.dart
index 4ae1ae2..f9d3b8f 100644
--- a/lib/src/views/settings/subscription/select_payment.view.dart
+++ b/lib/src/views/settings/subscription/select_payment.view.dart
@@ -111,6 +111,7 @@ class _SelectPaymentViewState extends State {
Padding(
padding: const EdgeInsets.all(16),
child: Card(
+ color: context.color.surfaceContainer,
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
@@ -193,6 +194,7 @@ class _SelectPaymentViewState extends State {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Card(
+ color: context.color.surfaceContainer,
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
@@ -215,6 +217,7 @@ class _SelectPaymentViewState extends State {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Card(
+ color: context.color.surfaceContainer,
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
diff --git a/lib/src/views/settings/subscription/subscription.view.dart b/lib/src/views/settings/subscription/subscription.view.dart
index 6d1ccbf..d87434a 100644
--- a/lib/src/views/settings/subscription/subscription.view.dart
+++ b/lib/src/views/settings/subscription/subscription.view.dart
@@ -444,6 +444,7 @@ class PlanCard extends StatelessWidget {
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
+ color: context.color.surfaceContainer,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Column(