diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..339e4ae --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: otsmr \ No newline at end of file diff --git a/.github/workflows/release_github.yml b/.github/workflows/release_github.yml new file mode 100644 index 0000000..4abd77b --- /dev/null +++ b/.github/workflows/release_github.yml @@ -0,0 +1,58 @@ +name: Github Release + +on: + push: + tags: + - "v*.*.*" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + channel: stable + - run: flutter pub get + - run: flutter analyze + - run: flutter test + + - name: Create key.properties file + run: | + echo "storePassword=${{ secrets.STORE_PASSWORD }}" >> ./android/key.properties + echo "keyPassword=${{ secrets.ALIAS_PASSWORD }}" >> ./android/key.properties + echo "keyAlias=androidreleasekey" >> key.properties + echo "storeFile=./android/keystore.jks" >> ./android/key.properties + run: base64 -d <<< $KEYSTORE_FILE > ./android/keystore.jks + + - name: Build Android APK + - run: flutter build apk --release --split-per-abi + + - name: Create Github Release + - uses: actions/upload-artifact@v4 + with: + name: release-apk + path: build/app/outputs/flutter-apk/*.apk + + - name: Generate Checksums + run: | + tree . + find app -type f -exec md5sum {} \; >> RELEASE.md5sum + find app -type f -exec sha256sum {} \; >> RELEASE.sha256sum + sed -i 's|app/.*/\([^/]*\)$|\1|' RELEASE.sha256sum RELEASE.md5sum + sed -i 's|app/||' RELEASE.sha256sum RELEASE.md5sum + + - name: Upload Release Binaries (stable) + if: ${{ !inputs.dry_run && inputs.channel == 'stable' }} + uses: ncipollo/release-action@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + tag: v${{ env.PUBSPEC_VERSION }} # mind the "v" prefix + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + omitPrereleaseDuringUpdate: true + allowUpdates: true + artifacts: app_*/**/*,RELEASE.sha256sum,RELEASE.md5sum \ No newline at end of file diff --git a/lib/app.dart b/lib/app.dart index a2a7fc2..0de5d7d 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,9 +1,5 @@ import 'dart:async'; -import 'dart:io'; -import 'package:cryptography_plus/cryptography_plus.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; @@ -16,7 +12,6 @@ import 'package:twonly/src/views/components/app_outdated.dart'; import 'package:twonly/src/views/home.view.dart'; import 'package:twonly/src/views/onboarding/onboarding.view.dart'; import 'package:twonly/src/views/onboarding/register.view.dart'; -import 'package:twonly/src/views/settings/help/changelog.view.dart'; class App extends StatefulWidget { const App({super.key}); diff --git a/lib/src/database/signal/connect_signed_pre_key_store.dart b/lib/src/database/signal/connect_signed_pre_key_store.dart index 26be8ed..91dcc5d 100644 --- a/lib/src/database/signal/connect_signed_pre_key_store.dart +++ b/lib/src/database/signal/connect_signed_pre_key_store.dart @@ -17,6 +17,7 @@ class ConnectSignedPreKeyStore extends SignedPreKeyStore { } final storeHashMap = json.decode(storeSerialized) as List; for (final item in storeHashMap) { + // ignore: avoid_dynamic_calls store[item[0] as int] = base64Decode(item[1] as String); } return store; diff --git a/lib/src/views/chats/chat_messages_components/chat_date_chip.dart b/lib/src/views/chats/chat_messages_components/chat_date_chip.dart index 132b871..77667d5 100644 --- a/lib/src/views/chats/chat_messages_components/chat_date_chip.dart +++ b/lib/src/views/chats/chat_messages_components/chat_date_chip.dart @@ -9,7 +9,7 @@ class ChatDateChip extends StatelessWidget { @override Widget build(BuildContext context) { - var formattedDate = item.isTime + final formattedDate = item.isTime ? DateFormat.Hm(Localizations.localeOf(context).toLanguageTag()) .format(item.time!) : '${DateFormat.Hm(Localizations.localeOf(context).toLanguageTag()).format(item.date!)} ${DateFormat.yMd(Localizations.localeOf(context).toLanguageTag()).format(item.date!)}'; diff --git a/lib/src/views/memories/memories_photo_slider.view.dart b/lib/src/views/memories/memories_photo_slider.view.dart index 62512d5..8ac1d3a 100644 --- a/lib/src/views/memories/memories_photo_slider.view.dart +++ b/lib/src/views/memories/memories_photo_slider.view.dart @@ -119,7 +119,7 @@ class _MemoriesPhotoSliderViewState extends State { alignment: Alignment.bottomRight, children: [ MediaViewSizing( - bottomNavigation: Container( + bottomNavigation: ColoredBox( color: context.color.surface, child: Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/src/views/settings/help/changelog.view.dart b/lib/src/views/settings/help/changelog.view.dart index adf7b2b..68f8d5b 100644 --- a/lib/src/views/settings/help/changelog.view.dart +++ b/lib/src/views/settings/help/changelog.view.dart @@ -4,7 +4,7 @@ import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; List parseMarkdown(BuildContext context, String markdown) { - List widgets = []; + final widgets = []; // Split the string into lines final lines = markdown.split('\n'); @@ -37,7 +37,7 @@ List parseMarkdown(BuildContext context, String markdown) { crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: EdgeInsets.only(top: 7), + padding: const EdgeInsets.only(top: 7), child: Icon( Icons.brightness_1, size: 7, diff --git a/lib/src/views/settings/help/help.view.dart b/lib/src/views/settings/help/help.view.dart index e2ae4d8..9c8476e 100644 --- a/lib/src/views/settings/help/help.view.dart +++ b/lib/src/views/settings/help/help.view.dart @@ -102,7 +102,7 @@ class HelpView extends StatelessWidget { }, ), ListTile( - title: const Text("Open Source"), + title: const Text('Open Source'), onTap: () { launchUrl(Uri.parse('https://github.com/twonlyapp/twonly-app')); }, @@ -127,17 +127,17 @@ class HelpView extends StatelessWidget { ), ListTile( onLongPress: () async { - bool? okay = await showAlertDialog( + final okay = await showAlertDialog( context, - "Delete Retransmission messages", - "Only do this if you know what you are doing :)", + 'Delete Retransmission messages', + 'Only do this if you know what you are doing :)', ); if (okay == true) { await twonlyDB.messageRetransmissionDao .clearRetransmissionTable(); } }, - title: Text( + title: const Text( 'Copyright twonly', style: TextStyle(color: Colors.grey, fontSize: 13), ), diff --git a/metadata/de-DE/full_description.txt b/metadata/de-DE/full_description.txt new file mode 100644 index 0000000..40a971e --- /dev/null +++ b/metadata/de-DE/full_description.txt @@ -0,0 +1,13 @@ +twonly, eine datenschutzfreundliche Möglichkeit sich mit Freunden durch sichere, spontane Bildübertragung zu verbinden. + +=> Unbeschwertes Teilen <= +Mit Ende-zu-Ende-Verschlüsselung genieße die Gewissheit, dass nur du und deine Freunde die Momente sehen können, die du teilst. + +=> Konzentriere dich auf das Teilen von Momenten <= +Verabschiede dich von süchtig machenden Funktionen! twonly wurde für das Teilen von Momenten geschaffen, frei von nutzlosen Ablenkungen oder Werbung. + +=> In Europa ansässig <= +twonly wird ausschließlich in Europa entwickelt und gehostet. Erstellt von einem Studenten, nicht von einem großen Tech-Unternehmen, das deine persönlichen Daten zum Profit verkauft. + +=> Du bist nicht das Produkt! <= +twonly wird klar und transparent durch eine monatliche Gebühr finanziert und nicht durch den Verkauf deiner Daten. \ No newline at end of file diff --git a/metadata/de-DE/images/featureGraphic.png b/metadata/de-DE/images/featureGraphic.png new file mode 100644 index 0000000..9b4ccb6 Binary files /dev/null and b/metadata/de-DE/images/featureGraphic.png differ diff --git a/metadata/de-DE/images/logo.png b/metadata/de-DE/images/logo.png new file mode 100644 index 0000000..20e4bbc Binary files /dev/null and b/metadata/de-DE/images/logo.png differ diff --git a/metadata/de-DE/images/phoneScreenshots/1.png b/metadata/de-DE/images/phoneScreenshots/1.png new file mode 100644 index 0000000..a8a40b0 Binary files /dev/null and b/metadata/de-DE/images/phoneScreenshots/1.png differ diff --git a/metadata/de-DE/images/phoneScreenshots/2.png b/metadata/de-DE/images/phoneScreenshots/2.png new file mode 100644 index 0000000..8635864 Binary files /dev/null and b/metadata/de-DE/images/phoneScreenshots/2.png differ diff --git a/metadata/de-DE/short_description.txt b/metadata/de-DE/short_description.txt new file mode 100644 index 0000000..c00ee8a --- /dev/null +++ b/metadata/de-DE/short_description.txt @@ -0,0 +1 @@ +Privat in Kontakt bleiben. \ No newline at end of file diff --git a/metadata/de-DE/title.txt b/metadata/de-DE/title.txt new file mode 100644 index 0000000..1aa421b --- /dev/null +++ b/metadata/de-DE/title.txt @@ -0,0 +1 @@ +twonly \ No newline at end of file diff --git a/metadata/en-US/full_description.txt b/metadata/en-US/full_description.txt new file mode 100644 index 0000000..09a8d95 --- /dev/null +++ b/metadata/en-US/full_description.txt @@ -0,0 +1,13 @@ +twonly, a privacy-friendly way to connect with friends through secure, spontaneous image sharing. + +=> Carefree sharing <= +With end-to-end encryption, enjoy the peace of mind that only you and your friends can see the moments you share. + +=> Focus on sharing moments <= +Say goodbye to addictive features! twonly was created for sharing moments, free from useless distractions or ads. + +=> Based in Europe <= +twonly is developed and hosted exclusively in Europe. Created by a student, not a big tech company selling your personal data for profit. + +=> You are not the product! <= +twonly is clearly and transparently funded by a monthly fee and not by selling your data. \ No newline at end of file diff --git a/metadata/en-US/images/featureGraphic.png b/metadata/en-US/images/featureGraphic.png new file mode 100644 index 0000000..9b4ccb6 Binary files /dev/null and b/metadata/en-US/images/featureGraphic.png differ diff --git a/metadata/en-US/images/logo.png b/metadata/en-US/images/logo.png new file mode 100644 index 0000000..20e4bbc Binary files /dev/null and b/metadata/en-US/images/logo.png differ diff --git a/metadata/en-US/images/phoneScreenshots/1.png b/metadata/en-US/images/phoneScreenshots/1.png new file mode 100644 index 0000000..ce0672f Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/1.png differ diff --git a/metadata/en-US/images/phoneScreenshots/2.png b/metadata/en-US/images/phoneScreenshots/2.png new file mode 100644 index 0000000..18455ec Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/2.png differ diff --git a/metadata/en-US/short_description.txt b/metadata/en-US/short_description.txt new file mode 100644 index 0000000..e08090d --- /dev/null +++ b/metadata/en-US/short_description.txt @@ -0,0 +1 @@ +Stay in touch privately. \ No newline at end of file diff --git a/metadata/en-US/title.txt b/metadata/en-US/title.txt new file mode 100644 index 0000000..1aa421b --- /dev/null +++ b/metadata/en-US/title.txt @@ -0,0 +1 @@ +twonly \ No newline at end of file