diff --git a/.gitignore b/.gitignore index bee4c81..e059815 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.log *.pyc *.swp +*.snap .DS_Store .atom/ .buildlog/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 07860ce..3cea1e6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -181,3 +181,37 @@ pages: - public only: - main + +build_linux: + stage: coverage + image: registry.gitlab.com/famedly/containers/flutter-dockerimages:dev + dependencies: [] + script: + - sudo apt update + - sudo apt install clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev + - flutter config --enable-linux-desktop + - flutter pub get + - flutter build linux --release + artifacts: + when: on_success + paths: + - build/linux/release/bundle/ + only: + - main + +snap:publish: + stage: publish + image: "cibuilds/snapcraft:core18" + only: + - tags + script: + - snapcraft + - echo $SNAPCRAFT_LOGIN_FILE | base64 --decode --ignore-garbage > snapcraft.login + - snapcraft login --with snapcraft.login + - snapcraft push --release=stable *.snap + - snapcraft logout + artifacts: + paths: + - './*.snap' + when: on_success + expire_in: 1 week diff --git a/CHANGELOG.md b/CHANGELOG.md index e4d83a6..a7aecbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### Features - Add ability to enable / disable emotes globally - Add ability to manage emote packs with different state keys +### Fixes +- Fix amoled / theme settings not always saving properly +- Show device name in account information correctly # Version 0.19.0 - 2020-09-21 ### Features diff --git a/lib/components/list_items/status_list_item.dart b/lib/components/list_items/status_list_item.dart index 7ed9680..1d5f272 100644 --- a/lib/components/list_items/status_list_item.dart +++ b/lib/components/list_items/status_list_item.dart @@ -17,7 +17,7 @@ class StatusListItem extends StatelessWidget { future: client.getProfileFromUserId(status.userId), builder: (context, snapshot) { final profile = - snapshot.data ?? Profile(client.userID, Uri.parse('')); + snapshot.data ?? Profile(status.userId.localpart, null); return InkWell( borderRadius: BorderRadius.circular(8), onTap: () => Navigator.of(context).push( diff --git a/lib/components/matrix.dart b/lib/components/matrix.dart index a09676f..62406bd 100644 --- a/lib/components/matrix.dart +++ b/lib/components/matrix.dart @@ -21,6 +21,7 @@ import '../utils/beautify_string_extension.dart'; import '../utils/famedlysdk_store.dart'; import '../utils/presence_extension.dart'; import '../views/key_verification.dart'; +import '../utils/platform_infos.dart'; import 'avatar.dart'; class Matrix extends StatefulWidget { @@ -211,7 +212,7 @@ class MatrixState extends State { final Set verificationMethods = { KeyVerificationMethod.numbers }; - if (!kIsWeb) { + if (PlatformInfos.isMobile) { // emojis don't show in web somehow verificationMethods.add(KeyVerificationMethod.emoji); } diff --git a/lib/components/theme_switcher.dart b/lib/components/theme_switcher.dart index 647ea5a..9b368bf 100644 --- a/lib/components/theme_switcher.dart +++ b/lib/components/theme_switcher.dart @@ -176,8 +176,9 @@ class ThemeSwitcherWidgetState extends State { Future loadSelection(MatrixState matrix) async { String item = await matrix.store.getItem('theme') ?? 'light'; - selectedTheme = - Themes.values.firstWhere((e) => e.toString() == 'Themes.' + item); + selectedTheme = Themes.values.firstWhere( + (e) => e.toString() == 'Themes.' + item, + orElse: () => Themes.system); amoledEnabled = (await matrix.store.getItem('amoled_enabled') ?? 'false') .toLowerCase() == @@ -240,26 +241,6 @@ class ThemeSwitcherWidgetState extends State { void setup() async { final matrix = Matrix.of(context); await loadSelection(matrix); - - if (selectedTheme == null) { - switchTheme(matrix, Themes.light, false); - } else { - switch (selectedTheme) { - case Themes.light: - switchTheme(matrix, Themes.light, false); - break; - case Themes.dark: - if (amoledEnabled) { - switchTheme(matrix, Themes.dark, true); - } else { - switchTheme(matrix, Themes.dark, false); - } - break; - case Themes.system: - switchTheme(matrix, Themes.system, false); - break; - } - } } @override diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index c45a6a0..6172189 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -23,7 +23,7 @@ "type": "text", "placeholders": {} }, - "accountInformation": "Account informations", + "accountInformation": "Account information", "@accountInformation": { "type": "text", "placeholders": {} @@ -159,6 +159,11 @@ "type": "text", "placeholders": {} }, + "changeDeviceName": "Change device name", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, "changedTheChatAvatar": "{username} changed the chat avatar", "@changedTheChatAvatar": { "type": "text", @@ -1207,7 +1212,7 @@ "type": "text", "placeholders": {} }, - "sentryInfo": "Informations about your privacy: https://sentry.io/security/", + "sentryInfo": "Information about your privacy: https://sentry.io/security/", "@sentryInfo": { "type": "text", "placeholders": {} @@ -1315,7 +1320,7 @@ "username": {} } }, - "sentCallInformations": "{senderName} sent call informations", + "sentCallInformations": "{senderName} sent call information", "@sentCallInformations": { "type": "text", "placeholders": { @@ -1723,4 +1728,4 @@ "type": "text", "placeholders": {} } -} +} \ No newline at end of file diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb index ce82ea1..ce3b836 100644 --- a/lib/l10n/intl_fr.arb +++ b/lib/l10n/intl_fr.arb @@ -23,7 +23,7 @@ "type": "text", "placeholders": {} }, - "accountInformation": "Informations du compte", + "accountInformation": "Informations sur le compte", "@accountInformation": { "type": "text", "placeholders": {} @@ -1702,5 +1702,20 @@ "@yourOwnUsername": { "type": "text", "placeholders": {} + }, + "privacy": "Vie privée", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Activer globalement le pack d'émoticônes", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Packs d'émoticônes pour le salon", + "@emotePacks": { + "type": "text", + "placeholders": {} } -} \ No newline at end of file +} diff --git a/lib/l10n/intl_hr.arb b/lib/l10n/intl_hr.arb index f9121cc..7620a59 100644 --- a/lib/l10n/intl_hr.arb +++ b/lib/l10n/intl_hr.arb @@ -1702,5 +1702,20 @@ "@yourOwnUsername": { "type": "text", "placeholders": {} + }, + "enableEmotesGlobally": "Aktiviraj paket emotikona globalno", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Paketi emotikona za sobu", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "privacy": "Privatnost", + "@privacy": { + "type": "text", + "placeholders": {} } -} \ No newline at end of file +} diff --git a/lib/l10n/intl_it.arb b/lib/l10n/intl_it.arb new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/lib/l10n/intl_it.arb @@ -0,0 +1 @@ +{} diff --git a/lib/l10n/intl_tr.arb b/lib/l10n/intl_tr.arb index 22f3ef5..1895c47 100644 --- a/lib/l10n/intl_tr.arb +++ b/lib/l10n/intl_tr.arb @@ -102,7 +102,7 @@ "type": "text", "placeholders": {} }, - "askVerificationRequest": "{username}'den gelen doğrulama talebini kabul etmek istiyor musunuz?", + "askVerificationRequest": "{username} kişisinden gelen bu doğrulama isteği kabul edilsin mi?", "@askVerificationRequest": { "type": "text", "placeholders": { @@ -119,7 +119,7 @@ "type": "text", "placeholders": {} }, - "banFromChat": "Sohbetten engellendiniz", + "banFromChat": "Sohbetten engelle", "@banFromChat": { "type": "text", "placeholders": {} @@ -129,7 +129,7 @@ "type": "text", "placeholders": {} }, - "bannedUser": "{username} engelledi: {targetName}", + "bannedUser": "{username}, {targetName} kişisini engelledi", "@bannedUser": { "type": "text", "placeholders": { @@ -249,7 +249,7 @@ "username": {} } }, - "changedTheRoomAliases": "", + "changedTheRoomAliases": "{username} oda takma adlarını değiştirdi", "@changedTheRoomAliases": { "type": "text", "placeholders": { @@ -268,7 +268,7 @@ "type": "text", "placeholders": {} }, - "changeTheHomeserver": "", + "changeTheHomeserver": "Ana sunucuyu değiştir", "@changeTheHomeserver": { "type": "text", "placeholders": {} @@ -293,7 +293,7 @@ "type": "text", "placeholders": {} }, - "channelCorruptedDecryptError": "", + "channelCorruptedDecryptError": "Şifreleme bozuldu", "@channelCorruptedDecryptError": { "type": "text", "placeholders": {} @@ -323,12 +323,12 @@ "type": "text", "placeholders": {} }, - "compareEmojiMatch": "", + "compareEmojiMatch": "Karşılaştırın ve aşağıdaki emojilerin diğer cihazdakilerle eşleştiğinden emin olun:", "@compareEmojiMatch": { "type": "text", "placeholders": {} }, - "compareNumbersMatch": "", + "compareNumbersMatch": "Karşılaştırın ve aşağıdaki numaraların diğer cihazdakilerle eşleştiğinden emin olun:", "@compareNumbersMatch": { "type": "text", "placeholders": {} @@ -353,7 +353,7 @@ "type": "text", "placeholders": {} }, - "contentViewer": "", + "contentViewer": "İçerik görüntüleyici", "@contentViewer": { "type": "text", "placeholders": {} @@ -380,7 +380,7 @@ "type": "text", "placeholders": {} }, - "couldNotSetDisplayname": "", + "couldNotSetDisplayname": "Görünen ad ayarlanamadı", "@couldNotSetDisplayname": { "type": "text", "placeholders": {} @@ -414,17 +414,17 @@ "type": "text", "placeholders": {} }, - "crossSigningDisabled": "", + "crossSigningDisabled": "Çapraz imzalama devre dışı bırakıldı", "@crossSigningDisabled": { "type": "text", "placeholders": {} }, - "crossSigningEnabled": "", + "crossSigningEnabled": "Çapraz imzalama etkinleştirildi", "@crossSigningEnabled": { "type": "text", "placeholders": {} }, - "currentlyActive": "", + "currentlyActive": "Şu anda etkin", "@currentlyActive": { "type": "text", "placeholders": {} @@ -469,7 +469,7 @@ "type": "text", "placeholders": {} }, - "deny": "", + "deny": "Reddet", "@deny": { "type": "text", "placeholders": {} @@ -484,12 +484,12 @@ "type": "text", "placeholders": {} }, - "discardPicture": "", + "discardPicture": "Resmi at", "@discardPicture": { "type": "text", "placeholders": {} }, - "displaynameHasBeenChanged": "", + "displaynameHasBeenChanged": "Görünen ad değiştirildi", "@displaynameHasBeenChanged": { "type": "text", "placeholders": {} @@ -499,52 +499,52 @@ "type": "text", "placeholders": {} }, - "downloadFile": "", + "downloadFile": "Dosyayı indir", "@downloadFile": { "type": "text", "placeholders": {} }, - "editDisplayname": "", + "editDisplayname": "Görünen adı düzenle", "@editDisplayname": { "type": "text", "placeholders": {} }, - "editJitsiInstance": "", + "editJitsiInstance": "Jitsi örneğini düzenle", "@editJitsiInstance": { "type": "text", "placeholders": {} }, - "emoteExists": "", + "emoteExists": "İfade zaten var!", "@emoteExists": { "type": "text", "placeholders": {} }, - "emoteInvalid": "", + "emoteInvalid": "Geçersiz ifade kısa kodu!", "@emoteInvalid": { "type": "text", "placeholders": {} }, - "emoteSettings": "", + "emoteSettings": "İfade Ayarları", "@emoteSettings": { "type": "text", "placeholders": {} }, - "emoteShortcode": "", + "emoteShortcode": "İfade kısa kodu", "@emoteShortcode": { "type": "text", "placeholders": {} }, - "emoteWarnNeedToPick": "", + "emoteWarnNeedToPick": "Bir ifade kısa kodu ve bir resim seçmeniz gerekiyor!", "@emoteWarnNeedToPick": { "type": "text", "placeholders": {} }, - "emptyChat": "", + "emptyChat": "Boş sohbet", "@emptyChat": { "type": "text", "placeholders": {} }, - "enableEncryptionWarning": "", + "enableEncryptionWarning": "Artık şifrelemeyi devre dışı bırakamayacaksınız. Emin misiniz?", "@enableEncryptionWarning": { "type": "text", "placeholders": {} @@ -559,7 +559,7 @@ "type": "text", "placeholders": {} }, - "encryptionNotEnabled": "", + "encryptionNotEnabled": "Şifreleme etkinleştirilmedi", "@encryptionNotEnabled": { "type": "text", "placeholders": {} @@ -579,7 +579,7 @@ "type": "text", "placeholders": {} }, - "enterYourHomeserver": "", + "enterYourHomeserver": "Ana sunucunuzu girin", "@enterYourHomeserver": { "type": "text", "placeholders": {} @@ -599,7 +599,7 @@ "type": "text", "placeholders": {} }, - "forward": "", + "forward": "İlet", "@forward": { "type": "text", "placeholders": {} @@ -609,12 +609,12 @@ "type": "text", "placeholders": {} }, - "fromJoining": "", + "fromJoining": "Katılmadan", "@fromJoining": { "type": "text", "placeholders": {} }, - "fromTheInvitation": "", + "fromTheInvitation": "Davetten", "@fromTheInvitation": { "type": "text", "placeholders": {} @@ -634,19 +634,19 @@ "type": "text", "placeholders": {} }, - "groupIsPublic": "", + "groupIsPublic": "Grup herkese açık", "@groupIsPublic": { "type": "text", "placeholders": {} }, - "groupWith": "", + "groupWith": "{displayname} ile grup", "@groupWith": { "type": "text", "placeholders": { "displayname": {} } }, - "guestsAreForbidden": "", + "guestsAreForbidden": "Misafirlere izin verilmiyor", "@guestsAreForbidden": { "type": "text", "placeholders": {} @@ -656,7 +656,7 @@ "type": "text", "placeholders": {} }, - "hasWithdrawnTheInvitationFor": "", + "hasWithdrawnTheInvitationFor": "{username}, {targetName} için daveti geri çekti", "@hasWithdrawnTheInvitationFor": { "type": "text", "placeholders": { @@ -669,44 +669,44 @@ "type": "text", "placeholders": {} }, - "homeserverIsNotCompatible": "", + "homeserverIsNotCompatible": "Ana sunucu uyumlu değil", "@homeserverIsNotCompatible": { "type": "text", "placeholders": {} }, - "id": "", + "id": "Kimlik", "@id": { "type": "text", "placeholders": {} }, - "identity": "", + "identity": "Kimlik", "@identity": { "type": "text", "placeholders": {} }, - "incorrectPassphraseOrKey": "", + "incorrectPassphraseOrKey": "Yanlış parola veya kurtarma anahtarı", "@incorrectPassphraseOrKey": { "type": "text", "placeholders": {} }, - "inviteContact": "", + "inviteContact": "Kişi davet et", "@inviteContact": { "type": "text", "placeholders": {} }, - "inviteContactToGroup": "", + "inviteContactToGroup": "Kişiyi {groupName} grubuna davet et", "@inviteContactToGroup": { "type": "text", "placeholders": { "groupName": {} } }, - "invited": "", + "invited": "Davet edildi", "@invited": { "type": "text", "placeholders": {} }, - "invitedUser": "", + "invitedUser": "{username}, {targetName} kişisini davet etti", "@invitedUser": { "type": "text", "placeholders": { @@ -719,7 +719,7 @@ "type": "text", "placeholders": {} }, - "inviteText": "", + "inviteText": "{username} sizi FluffyChat'e davet etti. \n1. FluffyChat kurun: https://fluffychat.im \n2. Kaydolun veya giriş yapın \n3. Davet bağlantısını açın: {link}", "@inviteText": { "type": "text", "placeholders": { @@ -727,7 +727,7 @@ "link": {} } }, - "isDeviceKeyCorrect": "", + "isDeviceKeyCorrect": "Aşağıdaki cihaz anahtarı doğru mu?", "@isDeviceKeyCorrect": { "type": "text", "placeholders": {} @@ -744,17 +744,17 @@ "username": {} } }, - "keysCached": "", + "keysCached": "Anahtarlar önbelleğe alındı", "@keysCached": { "type": "text", "placeholders": {} }, - "keysMissing": "", + "keysMissing": "Anahtarlar eksik", "@keysMissing": { "type": "text", "placeholders": {} }, - "kicked": "", + "kicked": "{username}, {targetName} kişisini attı", "@kicked": { "type": "text", "placeholders": { @@ -762,7 +762,7 @@ "targetName": {} } }, - "kickedAndBanned": "", + "kickedAndBanned": "{username}, {targetName} kişisini attı ve engelledi", "@kickedAndBanned": { "type": "text", "placeholders": { @@ -770,19 +770,19 @@ "targetName": {} } }, - "kickFromChat": "", + "kickFromChat": "Sohbetten at", "@kickFromChat": { "type": "text", "placeholders": {} }, - "lastActiveAgo": "", + "lastActiveAgo": "Son görülen: {localizedTimeShort}", "@lastActiveAgo": { "type": "text", "placeholders": { "localizedTimeShort": {} } }, - "lastSeenIp": "", + "lastSeenIp": "Son görülen IP", "@lastSeenIp": { "type": "text", "placeholders": {} @@ -797,7 +797,7 @@ "type": "text", "placeholders": {} }, - "leftTheChat": "", + "leftTheChat": "Sohbetten ayrıldı", "@leftTheChat": { "type": "text", "placeholders": {} @@ -812,7 +812,7 @@ "type": "text", "placeholders": {} }, - "loadCountMoreParticipants": "", + "loadCountMoreParticipants": "{count} katılımcı daha yükle", "@loadCountMoreParticipants": { "type": "text", "placeholders": { @@ -834,7 +834,7 @@ "type": "text", "placeholders": {} }, - "logInTo": "", + "logInTo": "{homeserver} üzerinde oturum aç", "@logInTo": { "type": "text", "placeholders": { @@ -846,17 +846,17 @@ "type": "text", "placeholders": {} }, - "makeAModerator": "", + "makeAModerator": "Moderatör yap", "@makeAModerator": { "type": "text", "placeholders": {} }, - "makeAnAdmin": "", + "makeAnAdmin": "Yönetici yap", "@makeAnAdmin": { "type": "text", "placeholders": {} }, - "makeSureTheIdentifierIsValid": "", + "makeSureTheIdentifierIsValid": "Tanımlayıcının geçerli olduğundan emin olun", "@makeSureTheIdentifierIsValid": { "type": "text", "placeholders": {} @@ -866,7 +866,7 @@ "type": "text", "placeholders": {} }, - "moderator": "", + "moderator": "Moderatör", "@moderator": { "type": "text", "placeholders": {} @@ -876,94 +876,94 @@ "type": "text", "placeholders": {} }, - "muteChat": "", + "muteChat": "Sohbeti sessize al", "@muteChat": { "type": "text", "placeholders": {} }, - "needPantalaimonWarning": "", + "needPantalaimonWarning": "Uçtan uca şifreleme kullanmak için şimdilik Pantalaimon'a ihtiyacınız olduğunu lütfen unutmayın.", "@needPantalaimonWarning": { "type": "text", "placeholders": {} }, - "newMessageInFluffyChat": "", + "newMessageInFluffyChat": "FluffyChat'te yeni mesaj", "@newMessageInFluffyChat": { "type": "text", "placeholders": {} }, - "newPrivateChat": "", + "newPrivateChat": "Yeni özel sohbet", "@newPrivateChat": { "type": "text", "placeholders": {} }, - "newVerificationRequest": "", + "newVerificationRequest": "Yeni doğrulama isteği!", "@newVerificationRequest": { "type": "text", "placeholders": {} }, - "noCrossSignBootstrap": "", + "noCrossSignBootstrap": "FluffyChat şu anda çapraz imzalamanın etkinleştirilmesini desteklemiyor. Lütfen Riot içinden etkinleştirin.", "@noCrossSignBootstrap": { "type": "text", "placeholders": {} }, - "noEmotesFound": "", + "noEmotesFound": "İfade bulunamadı. 😕", "@noEmotesFound": { "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "", + "noGoogleServicesWarning": "Görünüşe göre telefonunuzda Google hizmetleri yok. Bu, mahremiyetiniz için iyi bir karar! FluffyChat'te anlık bildirimler almak için microG kullanmanızı tavsiye ediyoruz: https://microg.org/", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} }, - "noMegolmBootstrap": "", + "noMegolmBootstrap": "FluffyChat şu anda çevrim içi anahtar yedeklemenin etkinleştirilmesini desteklemiyor. Lütfen Riot içinden etkinleştirin.", "@noMegolmBootstrap": { "type": "text", "placeholders": {} }, - "none": "", + "none": "Yok", "@none": { "type": "text", "placeholders": {} }, - "noPermission": "", + "noPermission": "İzin yok", "@noPermission": { "type": "text", "placeholders": {} }, - "noRoomsFound": "", + "noRoomsFound": "Oda bulunamadı...", "@noRoomsFound": { "type": "text", "placeholders": {} }, - "notSupportedInWeb": "", + "notSupportedInWeb": "Web'de desteklenmiyor", "@notSupportedInWeb": { "type": "text", "placeholders": {} }, - "numberSelected": "", + "numberSelected": "{number} seçildi", "@numberSelected": { "type": "text", "placeholders": { "number": {} } }, - "ok": "", + "ok": "tamam", "@ok": { "type": "text", "placeholders": {} }, - "onlineKeyBackupDisabled": "", + "onlineKeyBackupDisabled": "Çevrim içi anahtar yedekleme devre dışı bırakıldı", "@onlineKeyBackupDisabled": { "type": "text", "placeholders": {} }, - "onlineKeyBackupEnabled": "", + "onlineKeyBackupEnabled": "Çevrim içi anahtar yedekleme etkinleştirildi", "@onlineKeyBackupEnabled": { "type": "text", "placeholders": {} }, - "oopsSomethingWentWrong": "", + "oopsSomethingWentWrong": "Tüh, bir şeyler yanlış gitti...", "@oopsSomethingWentWrong": { "type": "text", "placeholders": {} @@ -983,12 +983,12 @@ "type": "text", "placeholders": {} }, - "participatingUserDevices": "", + "participatingUserDevices": "Katılan kullanıcı cihazları", "@participatingUserDevices": { "type": "text", "placeholders": {} }, - "passphraseOrKey": "", + "passphraseOrKey": "parola veya kurtarma anahtarı", "@passphraseOrKey": { "type": "text", "placeholders": {} @@ -998,12 +998,12 @@ "type": "text", "placeholders": {} }, - "pickImage": "", + "pickImage": "Resim seç", "@pickImage": { "type": "text", "placeholders": {} }, - "play": "", + "play": "{fileName} dosyasını oynat", "@play": { "type": "text", "placeholders": { @@ -1015,7 +1015,7 @@ "type": "text", "placeholders": {} }, - "pleaseEnterAMatrixIdentifier": "", + "pleaseEnterAMatrixIdentifier": "Lütfen bir matrix tanımlayıcısı girin", "@pleaseEnterAMatrixIdentifier": { "type": "text", "placeholders": {} @@ -1030,17 +1030,17 @@ "type": "text", "placeholders": {} }, - "publicRooms": "", + "publicRooms": "Herkese Açık Odalar", "@publicRooms": { "type": "text", "placeholders": {} }, - "recording": "", + "recording": "Kaydediliyor", "@recording": { "type": "text", "placeholders": {} }, - "redactedAnEvent": "", + "redactedAnEvent": "{username} bir etkinliği düzenledi", "@redactedAnEvent": { "type": "text", "placeholders": { @@ -1086,7 +1086,7 @@ "type": "text", "placeholders": {} }, - "removeExile": "", + "removeExile": "Engeli kaldır", "@removeExile": { "type": "text", "placeholders": {} @@ -1096,12 +1096,12 @@ "type": "text", "placeholders": {} }, - "renderRichContent": "", + "renderRichContent": "Zengin mesaj içeriğini görüntüle", "@renderRichContent": { "type": "text", "placeholders": {} }, - "reply": "", + "reply": "Yanıtla", "@reply": { "type": "text", "placeholders": {} @@ -1121,7 +1121,7 @@ "type": "text", "placeholders": {} }, - "roomHasBeenUpgraded": "", + "roomHasBeenUpgraded": "Oda yükseltildi", "@roomHasBeenUpgraded": { "type": "text", "placeholders": {} @@ -1174,7 +1174,7 @@ "type": "text", "placeholders": {} }, - "sendImage": "", + "sendImage": "Resim gönder", "@sendImage": { "type": "text", "placeholders": {} @@ -1347,7 +1347,7 @@ "type": "text", "placeholders": {} }, - "unbannedUser": "{username} engeli kaldırdı: {targetName}", + "unbannedUser": "{username}, {targetName} kişisinin engelini kaldırdı", "@unbannedUser": { "type": "text", "placeholders": { @@ -1355,7 +1355,7 @@ "targetName": {} } }, - "unblockDevice": "", + "unblockDevice": "Cihazın Engellemesini Kaldır", "@unblockDevice": { "type": "text", "placeholders": {} @@ -1370,7 +1370,7 @@ "type": "text", "placeholders": {} }, - "unknownEvent": "", + "unknownEvent": "Bilinmeyen etkinlik '{type}'", "@unknownEvent": { "type": "text", "placeholders": { @@ -1449,7 +1449,7 @@ "type": "text", "placeholders": {} }, - "userSentUnknownEvent": "", + "userSentUnknownEvent": "{username} bir {type} etkinliği gönderdi", "@userSentUnknownEvent": { "type": "text", "placeholders": { @@ -1527,7 +1527,7 @@ "type": "text", "placeholders": {} }, - "waitingPartnerNumbers": "", + "waitingPartnerNumbers": "Ortağın numaraları kabul etmesi bekleniyor...", "@waitingPartnerNumbers": { "type": "text", "placeholders": {} @@ -1596,5 +1596,126 @@ "@yourOwnUsername": { "type": "text", "placeholders": {} + }, + "warning": "Uyarı!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "unpin": "Sabitlemeyi kaldır", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} bir arama başlattı", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "sentCallInformations": "{senderName} arama bilgilerini gönderdi", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "sendVideo": "Video gönder", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Orijinali gönder", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Ses gönder", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "changesHaveBeenSaved": "Değişiklikler kaydedildi", + "@changesHaveBeenSaved": { + "type": "text", + "placeholders": {} + }, + "sentryInfo": "Gizliliğiniz hakkında bilgiler: https://sentry.io/security/", + "@sentryInfo": { + "type": "text", + "placeholders": {} + }, + "sendBugReports": "sentry.io ile hata raporları göndermeye izin ver", + "@sendBugReports": { + "type": "text", + "placeholders": {} + }, + "pin": "Sabitle", + "@pin": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "Parola değiştirildi", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "privacy": "Gizlilik", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "no": "Hayır", + "@no": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "Odaya katıl", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "Sizi rahatsız eden kullanıcıları yok sayabilirsiniz. Kişisel yok sayma listenizdeki kullanıcılardan herhangi bir mesaj veya oda daveti alamayacaksınız.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Kullanıcıyı yok say", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Yok sayılan kullanıcılar", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} aramayı sonlandırdı", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enableEmotesGlobally": "İfade paketini küresel olarak etkinleştir", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Oda için ifade paketleri", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Hesabı sil", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deactivateAccountWarning": "Bu, kullanıcı hesabınızı devre dışı bırakacak. Bu geri alınamaz! Emin misiniz?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} } -} \ No newline at end of file +} diff --git a/lib/utils/database/mobile.dart b/lib/utils/database/mobile.dart index d424e5f..30a2a75 100644 --- a/lib/utils/database/mobile.dart +++ b/lib/utils/database/mobile.dart @@ -2,6 +2,7 @@ import 'dart:ffi'; import 'dart:io'; import 'dart:isolate'; import 'package:famedlysdk/famedlysdk.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:sqflite/sqflite.dart' show getDatabasesPath; import 'package:path/path.dart' as p; import 'package:flutter/material.dart'; @@ -64,22 +65,17 @@ Future constructDb( final isolate = (await receivePort.first as MoorIsolate); return Database.connect(await isolate.connect()); } else if (Platform.isLinux) { - debugPrint('[Moor] using desktop moor'); - open.overrideFor(OperatingSystem.linux, _openOnLinux); - return Database(moor.VmDatabase.memory()); + debugPrint('[Moor] using Linux desktop moor'); + final appDocDir = await getApplicationSupportDirectory(); + return Database(moor.VmDatabase(File('${appDocDir.path}/$filename'))); } else if (Platform.isWindows) { - debugPrint('[Moor] using desktop moor'); - open.overrideFor(OperatingSystem.linux, _openOnWindows); + debugPrint('[Moor] using Windows desktop moor'); + open.overrideFor(OperatingSystem.windows, _openOnWindows); return Database(moor.VmDatabase.memory()); } throw Exception('Platform not supported'); } -DynamicLibrary _openOnLinux() { - final libraryNextToScript = File('/usr/lib/x86_64-linux-gnu/libsqlite3.so'); - return DynamicLibrary.open(libraryNextToScript.path); -} - DynamicLibrary _openOnWindows() { final script = File(Platform.script.toFilePath()); final libraryNextToScript = File('${script.path}/sqlite3.dll'); diff --git a/lib/views/app_info.dart b/lib/views/app_info.dart index 462be7e..cd826c9 100644 --- a/lib/views/app_info.dart +++ b/lib/views/app_info.dart @@ -37,7 +37,9 @@ class AppInfo extends StatelessWidget { ), ListTile( title: Text('Device name:'), - subtitle: Text(client.deviceName), + subtitle: Text(client.userDeviceKeys[client.userID] + ?.deviceKeys[client.deviceID]?.deviceDisplayName ?? + L10n.of(context).unknownDevice), ), ListTile( title: Text('Device ID:'), diff --git a/lib/views/chat.dart b/lib/views/chat.dart index 1bd701b..acaf76d 100644 --- a/lib/views/chat.dart +++ b/lib/views/chat.dart @@ -227,7 +227,7 @@ class _ChatState extends State<_Chat> { } void sendImageAction(BuildContext context) async { - MatrixFile file; + MatrixImageFile file; if (PlatformInfos.isMobile) { final result = await ImagePicker().getImage( source: ImageSource.gallery, @@ -235,7 +235,7 @@ class _ChatState extends State<_Chat> { maxWidth: 1600, maxHeight: 1600); if (result == null) return; - file = MatrixFile( + file = MatrixImageFile( bytes: await result.readAsBytes(), name: result.path, ); @@ -243,7 +243,7 @@ class _ChatState extends State<_Chat> { final result = await FilePickerCross.importFromStorage(type: FileTypeCross.image); if (result == null) return; - file = MatrixFile( + file = MatrixImageFile( bytes: result.toUint8List(), name: result.fileName, ); diff --git a/lib/views/chat_list.dart b/lib/views/chat_list.dart index e126b5f..b0aa931 100644 --- a/lib/views/chat_list.dart +++ b/lib/views/chat_list.dart @@ -456,12 +456,16 @@ class _ChatListState extends State { ConnectionStatusHeader(), Expanded( child: StreamBuilder( - stream: Matrix.of(context) - .client - .onSync - .stream - .where((s) => - s.hasRoomUpdate || s.hasPresenceUpdate), + stream: + Matrix.of(context).client.onSync.stream.where( + (s) => + s.hasRoomUpdate || + s.accountData + .where((a) => + a.type == + MatrixState.userStatusesType) + .isNotEmpty, + ), builder: (context, snapshot) { return FutureBuilder( future: waitForFirstSync(context), diff --git a/lib/views/settings_devices.dart b/lib/views/settings_devices.dart index 1894b13..a1a5620 100644 --- a/lib/views/settings_devices.dart +++ b/lib/views/settings_devices.dart @@ -56,6 +56,19 @@ class DevicesSettingsState extends State { } } + void _renameDeviceAction(BuildContext context, Device device) async { + final displayName = await SimpleDialogs(context).enterText( + hintText: device.displayName, + labelText: L10n.of(context).changeDeviceName, + ); + if (displayName == null) return; + await SimpleDialogs(context).tryRequestWithLoadingDialog( + Matrix.of(context) + .client + .setDeviceMetadata(device.deviceId, displayName: displayName), + ); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -117,6 +130,7 @@ class DevicesSettingsState extends State { itemBuilder: (BuildContext context, int i) => UserDeviceListItem( devices[i], + rename: (d) => _renameDeviceAction(context, d), remove: (d) => _removeDevicesAction(context, [d]), ), ), @@ -132,23 +146,34 @@ class DevicesSettingsState extends State { class UserDeviceListItem extends StatelessWidget { final Device userDevice; final Function remove; + final Function rename; - const UserDeviceListItem(this.userDevice, {this.remove, Key key}) + const UserDeviceListItem(this.userDevice, {this.remove, this.rename, Key key}) : super(key: key); @override Widget build(BuildContext context) { return PopupMenuButton( onSelected: (String action) { - if (action == 'remove' && remove != null) { - remove(userDevice); + switch (action) { + case 'remove': + if (remove != null) remove(userDevice); + break; + case 'rename': + if (rename != null) rename(userDevice); } }, itemBuilder: (BuildContext context) => [ + PopupMenuItem( + value: 'rename', + child: Text(L10n.of(context).changeDeviceName), + ), PopupMenuItem( value: 'remove', - child: Text(L10n.of(context).removeDevice, - style: TextStyle(color: Colors.red)), + child: Text( + L10n.of(context).removeDevice, + style: TextStyle(color: Colors.red), + ), ), ], child: ListTile( diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 34af8c5..5e82bb4 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -45,6 +45,14 @@ apply_standard_settings(${BINARY_NAME}) target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) add_dependencies(${BINARY_NAME} flutter_assemble) +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) # Generated plugin build rules, which manage building the plugins and adding # them to the application. diff --git a/pubspec.lock b/pubspec.lock index b53e030..4f7308f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -325,7 +325,7 @@ packages: name: flutter_matrix_html url: "https://pub.dartlang.org" source: hosted - version: "0.1.5" + version: "0.1.7" flutter_olm: dependency: "direct main" description: @@ -967,7 +967,7 @@ packages: source: hosted version: "1.0.8" url_launcher_web: - dependency: "direct main" + dependency: transitive description: name: url_launcher_web url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index f3b9153..6705045 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,8 +30,7 @@ dependencies: localstorage: ^3.0.1+4 file_picker_cross: ^4.2.2 image_picker: ^0.6.7+11 - url_launcher: ^5.4.1 - url_launcher_web: ^0.1.0 + url_launcher: ^5.7.2 cached_network_image: ^2.3.2+1 firebase_messaging: ^7.0.2 flutter_local_notifications: ^1.4.3 @@ -49,7 +48,7 @@ dependencies: open_file: ^3.0.1 mime_type: ^0.3.0 bot_toast: ^3.0.0 - flutter_matrix_html: ^0.1.5 + flutter_matrix_html: ^0.1.7 moor: ^3.3.1 sqlite3_flutter_libs: ^0.2.0 sqlite3: ^0.1.4 @@ -85,7 +84,7 @@ flutter_icons: # The following section is specific to Flutter. flutter: - # Adds code generation (synthetic package) support + # Adds code generation (synthetic package) support generate: true