add fastlane data and github action
1
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
github: otsmr
|
||||
58
.github/workflows/release_github.yml
vendored
Normal file
|
|
@ -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
|
||||
|
|
@ -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});
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class ConnectSignedPreKeyStore extends SignedPreKeyStore {
|
|||
}
|
||||
final storeHashMap = json.decode(storeSerialized) as List<dynamic>;
|
||||
for (final item in storeHashMap) {
|
||||
// ignore: avoid_dynamic_calls
|
||||
store[item[0] as int] = base64Decode(item[1] as String);
|
||||
}
|
||||
return store;
|
||||
|
|
|
|||
|
|
@ -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!)}';
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ class _MemoriesPhotoSliderViewState extends State<MemoriesPhotoSliderView> {
|
|||
alignment: Alignment.bottomRight,
|
||||
children: <Widget>[
|
||||
MediaViewSizing(
|
||||
bottomNavigation: Container(
|
||||
bottomNavigation: ColoredBox(
|
||||
color: context.color.surface,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import 'package:twonly/src/utils/misc.dart';
|
|||
import 'package:twonly/src/utils/storage.dart';
|
||||
|
||||
List<Widget> parseMarkdown(BuildContext context, String markdown) {
|
||||
List<Widget> widgets = [];
|
||||
final widgets = <Widget>[];
|
||||
// Split the string into lines
|
||||
final lines = markdown.split('\n');
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ List<Widget> 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,
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
|
|
|
|||
13
metadata/de-DE/full_description.txt
Normal file
|
|
@ -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.
|
||||
BIN
metadata/de-DE/images/featureGraphic.png
Normal file
|
After Width: | Height: | Size: 198 KiB |
BIN
metadata/de-DE/images/logo.png
Normal file
|
After Width: | Height: | Size: 7 KiB |
BIN
metadata/de-DE/images/phoneScreenshots/1.png
Normal file
|
After Width: | Height: | Size: 322 KiB |
BIN
metadata/de-DE/images/phoneScreenshots/2.png
Normal file
|
After Width: | Height: | Size: 2.7 MiB |
1
metadata/de-DE/short_description.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
Privat in Kontakt bleiben.
|
||||
1
metadata/de-DE/title.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
twonly
|
||||
13
metadata/en-US/full_description.txt
Normal file
|
|
@ -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.
|
||||
BIN
metadata/en-US/images/featureGraphic.png
Normal file
|
After Width: | Height: | Size: 198 KiB |
BIN
metadata/en-US/images/logo.png
Normal file
|
After Width: | Height: | Size: 7 KiB |
BIN
metadata/en-US/images/phoneScreenshots/1.png
Normal file
|
After Width: | Height: | Size: 318 KiB |
BIN
metadata/en-US/images/phoneScreenshots/2.png
Normal file
|
After Width: | Height: | Size: 2.7 MiB |
1
metadata/en-US/short_description.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
Stay in touch privately.
|
||||
1
metadata/en-US/title.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
twonly
|
||||