mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 07:48:40 +00:00
fix #247
This commit is contained in:
parent
ad8dea4fbf
commit
6d1643848f
13 changed files with 1025 additions and 1473 deletions
|
|
@ -3,9 +3,10 @@
|
|||
## 0.0.58
|
||||
|
||||
- twonly now has a free plan and is now financed by donations and an optional subscription with more features (coming soon)
|
||||
- Implementing iOS gestures to close images
|
||||
- Improved the chat messages view, including better citation view and display times.
|
||||
- Updated onboarding screens and simplified the registration view
|
||||
- The sender is displayed in the top right corner when a media file is opened.
|
||||
- iOS gestures to close images
|
||||
- Improved chat messages view, including better citation view and display times
|
||||
- onboarding screens updated and registration view simplified
|
||||
- The sender is displayed in the top right corner when a media file is opened
|
||||
- Images are now stored as WebP to save storage
|
||||
- Button to report users
|
||||
- Multiple bug fixes
|
||||
|
|
@ -219,6 +219,9 @@ String getContactDisplayName(Contact user) {
|
|||
if (user.deleted) {
|
||||
name = applyStrikethrough(name);
|
||||
}
|
||||
if (name.length > 12) {
|
||||
return '${name.substring(0, 12)} ...';
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -331,5 +331,8 @@
|
|||
"doubleClickToReopen": "Doppelklicken zum\nerneuten Öffnen.",
|
||||
"retransmissionRequested": "Wird erneut versucht.",
|
||||
"testPaymentMethod": "Vielen Dank für dein Interesse an einem kostenpflichtigen Tarif. Die kostenpflichtigen Pläne sind derzeit noch deaktiviert. Sie werden aber bald aktiviert!",
|
||||
"openChangeLog": "Changelog automatisch öffnen"
|
||||
"openChangeLog": "Changelog automatisch öffnen",
|
||||
"reportUserTitle": "Melde {username}",
|
||||
"reportUserReason": "Meldegrund",
|
||||
"reportUser": "Benutzer melden"
|
||||
}
|
||||
|
|
@ -487,5 +487,8 @@
|
|||
"doubleClickToReopen": "Double-click\nto open again",
|
||||
"retransmissionRequested": "Retransmission requested",
|
||||
"testPaymentMethod": "Thanks for the interest in a paid plan. Currently the paid plans are still deactivated. But they will be activated soon!",
|
||||
"openChangeLog": "Open changelog automatically"
|
||||
"openChangeLog": "Open changelog automatically",
|
||||
"reportUserTitle": "Report {username}",
|
||||
"reportUserReason": "Reporting reason",
|
||||
"reportUser": "Report user"
|
||||
}
|
||||
|
|
@ -2029,6 +2029,24 @@ abstract class AppLocalizations {
|
|||
/// In en, this message translates to:
|
||||
/// **'Open changelog automatically'**
|
||||
String get openChangeLog;
|
||||
|
||||
/// No description provided for @reportUserTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Report {username}'**
|
||||
String reportUserTitle(Object username);
|
||||
|
||||
/// No description provided for @reportUserReason.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Reporting reason'**
|
||||
String get reportUserReason;
|
||||
|
||||
/// No description provided for @reportUser.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Report user'**
|
||||
String get reportUser;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
|
|
|||
|
|
@ -1076,4 +1076,15 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get openChangeLog => 'Changelog automatisch öffnen';
|
||||
|
||||
@override
|
||||
String reportUserTitle(Object username) {
|
||||
return 'Melde $username';
|
||||
}
|
||||
|
||||
@override
|
||||
String get reportUserReason => 'Meldegrund';
|
||||
|
||||
@override
|
||||
String get reportUser => 'Benutzer melden';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1070,4 +1070,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
|
||||
@override
|
||||
String get openChangeLog => 'Open changelog automatically';
|
||||
|
||||
@override
|
||||
String reportUserTitle(Object username) {
|
||||
return 'Report $username';
|
||||
}
|
||||
|
||||
@override
|
||||
String get reportUserReason => 'Reporting reason';
|
||||
|
||||
@override
|
||||
String get reportUser => 'Report user';
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -156,8 +156,9 @@ const ApplicationData$json = {
|
|||
{'1': 'getsignedprekeybyuserid', '3': 22, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.GetSignedPreKeyByUserId', '9': 0, '10': 'getsignedprekeybyuserid'},
|
||||
{'1': 'updatesignedprekey', '3': 23, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.UpdateSignedPreKey', '9': 0, '10': 'updatesignedprekey'},
|
||||
{'1': 'deleteaccount', '3': 24, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.DeleteAccount', '9': 0, '10': 'deleteaccount'},
|
||||
{'1': 'reportuser', '3': 25, '4': 1, '5': 11, '6': '.client_to_server.ApplicationData.ReportUser', '9': 0, '10': 'reportuser'},
|
||||
],
|
||||
'3': [ApplicationData_TextMessage$json, ApplicationData_GetUserByUsername$json, ApplicationData_UpdateGoogleFcmToken$json, ApplicationData_GetUserById$json, ApplicationData_RedeemVoucher$json, ApplicationData_SwitchToPayedPlan$json, ApplicationData_UpdatePlanOptions$json, ApplicationData_CreateVoucher$json, ApplicationData_GetLocation$json, ApplicationData_GetVouchers$json, ApplicationData_GetAvailablePlans$json, ApplicationData_GetAddAccountsInvites$json, ApplicationData_GetCurrentPlanInfos$json, ApplicationData_RedeemAdditionalCode$json, ApplicationData_RemoveAdditionalUser$json, ApplicationData_GetPrekeysByUserId$json, ApplicationData_GetSignedPreKeyByUserId$json, ApplicationData_UpdateSignedPreKey$json, ApplicationData_DownloadDone$json, ApplicationData_DeleteAccount$json],
|
||||
'3': [ApplicationData_TextMessage$json, ApplicationData_GetUserByUsername$json, ApplicationData_UpdateGoogleFcmToken$json, ApplicationData_GetUserById$json, ApplicationData_RedeemVoucher$json, ApplicationData_SwitchToPayedPlan$json, ApplicationData_UpdatePlanOptions$json, ApplicationData_CreateVoucher$json, ApplicationData_GetLocation$json, ApplicationData_GetVouchers$json, ApplicationData_GetAvailablePlans$json, ApplicationData_GetAddAccountsInvites$json, ApplicationData_GetCurrentPlanInfos$json, ApplicationData_RedeemAdditionalCode$json, ApplicationData_RemoveAdditionalUser$json, ApplicationData_GetPrekeysByUserId$json, ApplicationData_GetSignedPreKeyByUserId$json, ApplicationData_UpdateSignedPreKey$json, ApplicationData_DownloadDone$json, ApplicationData_ReportUser$json, ApplicationData_DeleteAccount$json],
|
||||
'8': [
|
||||
{'1': 'ApplicationData'},
|
||||
],
|
||||
|
|
@ -309,6 +310,15 @@ const ApplicationData_DownloadDone$json = {
|
|||
],
|
||||
};
|
||||
|
||||
@$core.Deprecated('Use applicationDataDescriptor instead')
|
||||
const ApplicationData_ReportUser$json = {
|
||||
'1': 'ReportUser',
|
||||
'2': [
|
||||
{'1': 'reported_user_id', '3': 1, '4': 1, '5': 3, '10': 'reportedUserId'},
|
||||
{'1': 'reason', '3': 2, '4': 1, '5': 9, '10': 'reason'},
|
||||
],
|
||||
};
|
||||
|
||||
@$core.Deprecated('Use applicationDataDescriptor instead')
|
||||
const ApplicationData_DeleteAccount$json = {
|
||||
'1': 'DeleteAccount',
|
||||
|
|
@ -351,26 +361,29 @@ final $typed_data.Uint8List applicationDataDescriptor = $convert.base64Decode(
|
|||
'cHJla2V5Ynl1c2VyaWQSZgoSdXBkYXRlc2lnbmVkcHJla2V5GBcgASgLMjQuY2xpZW50X3RvX3'
|
||||
'NlcnZlci5BcHBsaWNhdGlvbkRhdGEuVXBkYXRlU2lnbmVkUHJlS2V5SABSEnVwZGF0ZXNpZ25l'
|
||||
'ZHByZWtleRJXCg1kZWxldGVhY2NvdW50GBggASgLMi8uY2xpZW50X3RvX3NlcnZlci5BcHBsaW'
|
||||
'NhdGlvbkRhdGEuRGVsZXRlQWNjb3VudEgAUg1kZWxldGVhY2NvdW50GmoKC1RleHRNZXNzYWdl'
|
||||
'EhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBISCgRib2R5GAMgASgMUgRib2R5EiAKCXB1c2hfZG'
|
||||
'F0YRgEIAEoDEgAUghwdXNoRGF0YYgBAUIMCgpfcHVzaF9kYXRhGi8KEUdldFVzZXJCeVVzZXJu'
|
||||
'YW1lEhoKCHVzZXJuYW1lGAEgASgJUgh1c2VybmFtZRo1ChRVcGRhdGVHb29nbGVGY21Ub2tlbh'
|
||||
'IdCgpnb29nbGVfZmNtGAEgASgJUglnb29nbGVGY20aJgoLR2V0VXNlckJ5SWQSFwoHdXNlcl9p'
|
||||
'ZBgBIAEoA1IGdXNlcklkGikKDVJlZGVlbVZvdWNoZXISGAoHdm91Y2hlchgBIAEoCVIHdm91Y2'
|
||||
'hlchpwChFTd2l0Y2hUb1BheWVkUGxhbhIXCgdwbGFuX2lkGAEgASgJUgZwbGFuSWQSHwoLcGF5'
|
||||
'X21vbnRobHkYAiABKAhSCnBheU1vbnRobHkSIQoMYXV0b19yZW5ld2FsGAMgASgIUgthdXRvUm'
|
||||
'VuZXdhbBo2ChFVcGRhdGVQbGFuT3B0aW9ucxIhCgxhdXRvX3JlbmV3YWwYASABKAhSC2F1dG9S'
|
||||
'ZW5ld2FsGjAKDUNyZWF0ZVZvdWNoZXISHwoLdmFsdWVfY2VudHMYASABKA1SCnZhbHVlQ2VudH'
|
||||
'MaDQoLR2V0TG9jYXRpb24aDQoLR2V0Vm91Y2hlcnMaEwoRR2V0QXZhaWxhYmxlUGxhbnMaFwoV'
|
||||
'R2V0QWRkQWNjb3VudHNJbnZpdGVzGhUKE0dldEN1cnJlbnRQbGFuSW5mb3MaNwoUUmVkZWVtQW'
|
||||
'RkaXRpb25hbENvZGUSHwoLaW52aXRlX2NvZGUYAiABKAlSCmludml0ZUNvZGUaLwoUUmVtb3Zl'
|
||||
'QWRkaXRpb25hbFVzZXISFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkGi0KEkdldFByZWtleXNCeV'
|
||||
'VzZXJJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQaMgoXR2V0U2lnbmVkUHJlS2V5QnlVc2Vy'
|
||||
'SWQSFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkGpsBChJVcGRhdGVTaWduZWRQcmVLZXkSKAoQc2'
|
||||
'lnbmVkX3ByZWtleV9pZBgBIAEoA1IOc2lnbmVkUHJla2V5SWQSIwoNc2lnbmVkX3ByZWtleRgC'
|
||||
'IAEoDFIMc2lnbmVkUHJla2V5EjYKF3NpZ25lZF9wcmVrZXlfc2lnbmF0dXJlGAMgASgMUhVzaW'
|
||||
'duZWRQcmVrZXlTaWduYXR1cmUaNQoMRG93bmxvYWREb25lEiUKDmRvd25sb2FkX3Rva2VuGAEg'
|
||||
'ASgMUg1kb3dubG9hZFRva2VuGg8KDURlbGV0ZUFjY291bnRCEQoPQXBwbGljYXRpb25EYXRh');
|
||||
'NhdGlvbkRhdGEuRGVsZXRlQWNjb3VudEgAUg1kZWxldGVhY2NvdW50Ek4KCnJlcG9ydHVzZXIY'
|
||||
'GSABKAsyLC5jbGllbnRfdG9fc2VydmVyLkFwcGxpY2F0aW9uRGF0YS5SZXBvcnRVc2VySABSCn'
|
||||
'JlcG9ydHVzZXIaagoLVGV4dE1lc3NhZ2USFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkEhIKBGJv'
|
||||
'ZHkYAyABKAxSBGJvZHkSIAoJcHVzaF9kYXRhGAQgASgMSABSCHB1c2hEYXRhiAEBQgwKCl9wdX'
|
||||
'NoX2RhdGEaLwoRR2V0VXNlckJ5VXNlcm5hbWUSGgoIdXNlcm5hbWUYASABKAlSCHVzZXJuYW1l'
|
||||
'GjUKFFVwZGF0ZUdvb2dsZUZjbVRva2VuEh0KCmdvb2dsZV9mY20YASABKAlSCWdvb2dsZUZjbR'
|
||||
'omCgtHZXRVc2VyQnlJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQaKQoNUmVkZWVtVm91Y2hl'
|
||||
'chIYCgd2b3VjaGVyGAEgASgJUgd2b3VjaGVyGnAKEVN3aXRjaFRvUGF5ZWRQbGFuEhcKB3BsYW'
|
||||
'5faWQYASABKAlSBnBsYW5JZBIfCgtwYXlfbW9udGhseRgCIAEoCFIKcGF5TW9udGhseRIhCgxh'
|
||||
'dXRvX3JlbmV3YWwYAyABKAhSC2F1dG9SZW5ld2FsGjYKEVVwZGF0ZVBsYW5PcHRpb25zEiEKDG'
|
||||
'F1dG9fcmVuZXdhbBgBIAEoCFILYXV0b1JlbmV3YWwaMAoNQ3JlYXRlVm91Y2hlchIfCgt2YWx1'
|
||||
'ZV9jZW50cxgBIAEoDVIKdmFsdWVDZW50cxoNCgtHZXRMb2NhdGlvbhoNCgtHZXRWb3VjaGVycx'
|
||||
'oTChFHZXRBdmFpbGFibGVQbGFucxoXChVHZXRBZGRBY2NvdW50c0ludml0ZXMaFQoTR2V0Q3Vy'
|
||||
'cmVudFBsYW5JbmZvcxo3ChRSZWRlZW1BZGRpdGlvbmFsQ29kZRIfCgtpbnZpdGVfY29kZRgCIA'
|
||||
'EoCVIKaW52aXRlQ29kZRovChRSZW1vdmVBZGRpdGlvbmFsVXNlchIXCgd1c2VyX2lkGAEgASgD'
|
||||
'UgZ1c2VySWQaLQoSR2V0UHJla2V5c0J5VXNlcklkEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZB'
|
||||
'oyChdHZXRTaWduZWRQcmVLZXlCeVVzZXJJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQamwEK'
|
||||
'ElVwZGF0ZVNpZ25lZFByZUtleRIoChBzaWduZWRfcHJla2V5X2lkGAEgASgDUg5zaWduZWRQcm'
|
||||
'VrZXlJZBIjCg1zaWduZWRfcHJla2V5GAIgASgMUgxzaWduZWRQcmVrZXkSNgoXc2lnbmVkX3By'
|
||||
'ZWtleV9zaWduYXR1cmUYAyABKAxSFXNpZ25lZFByZWtleVNpZ25hdHVyZRo1CgxEb3dubG9hZE'
|
||||
'RvbmUSJQoOZG93bmxvYWRfdG9rZW4YASABKAxSDWRvd25sb2FkVG9rZW4aTgoKUmVwb3J0VXNl'
|
||||
'chIoChByZXBvcnRlZF91c2VyX2lkGAEgASgDUg5yZXBvcnRlZFVzZXJJZBIWCgZyZWFzb24YAi'
|
||||
'ABKAlSBnJlYXNvbhoPCg1EZWxldGVBY2NvdW50QhEKD0FwcGxpY2F0aW9uRGF0YQ==');
|
||||
|
||||
@$core.Deprecated('Use responseDescriptor instead')
|
||||
const Response$json = {
|
||||
|
|
|
|||
|
|
@ -576,6 +576,15 @@ class ApiService {
|
|||
return sendRequestSync(req);
|
||||
}
|
||||
|
||||
Future<Result> reportUser(int userId, String reason) async {
|
||||
final get = ApplicationData_ReportUser()
|
||||
..reportedUserId = Int64(userId)
|
||||
..reason = reason;
|
||||
final appData = ApplicationData()..reportuser = get;
|
||||
final req = createClientToServerFromApplicationData(appData);
|
||||
return sendRequestSync(req);
|
||||
}
|
||||
|
||||
Future<Result> deleteAccount() async {
|
||||
final get = ApplicationData_DeleteAccount();
|
||||
final appData = ApplicationData()..deleteaccount = get;
|
||||
|
|
|
|||
|
|
@ -317,10 +317,10 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
|||
return;
|
||||
}
|
||||
|
||||
widget.selectedCameraDetails.scaleFactor =
|
||||
// ignore: avoid_dynamic_calls
|
||||
(baseScaleFactor + (basePanY - (details.localPosition.dy as int)) / 30)
|
||||
.clamp(1, widget.selectedCameraDetails.maxAvailableZoom);
|
||||
widget.selectedCameraDetails.scaleFactor = (baseScaleFactor +
|
||||
// ignore: avoid_dynamic_calls
|
||||
(basePanY - (details.localPosition.dy as double)) / 30)
|
||||
.clamp(1, widget.selectedCameraDetails.maxAvailableZoom);
|
||||
|
||||
await widget.cameraController!
|
||||
.setZoomLevel(widget.selectedCameraDetails.scaleFactor);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,38 @@ class _ContactViewState extends State<ContactView> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> handleReportUser(Contact contact) async {
|
||||
final reason = await showReportDialog(context, contact);
|
||||
if (reason == null) return;
|
||||
final res = await apiService.reportUser(contact.userId, reason);
|
||||
if (!mounted) return;
|
||||
if (res.isSuccess) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Benutzer wurde gemeldet.'),
|
||||
duration: Duration(seconds: 3),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Es ist ein Fehler aufgetreten. Bitte versuche es später erneut.'),
|
||||
duration: Duration(seconds: 3),
|
||||
),
|
||||
);
|
||||
}
|
||||
// if (block) {
|
||||
// const update = ContactsCompanion(blocked: Value(true));
|
||||
// if (context.mounted) {
|
||||
// await twonlyDB.contactsDao.updateContact(contact.userId, update);
|
||||
// }
|
||||
// if (mounted) {
|
||||
// Navigator.popUntil(context, (route) => route.isFirst);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final contact = twonlyDB.contactsDao
|
||||
|
|
@ -146,9 +178,13 @@ class _ContactViewState extends State<ContactView> {
|
|||
}
|
||||
},
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.flag,
|
||||
text: context.lang.reportUser,
|
||||
onTap: () => handleReportUser(contact),
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.ban,
|
||||
color: Colors.red,
|
||||
text: context.lang.contactBlock,
|
||||
onTap: () => handleUserBlockRequest(contact),
|
||||
),
|
||||
|
|
@ -202,3 +238,39 @@ Future<String?> showNicknameChangeDialog(
|
|||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<String?> showReportDialog(
|
||||
BuildContext context,
|
||||
Contact contact,
|
||||
) {
|
||||
final controller = TextEditingController();
|
||||
|
||||
return showDialog<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title:
|
||||
Text(context.lang.reportUserTitle(getContactDisplayName(contact))),
|
||||
content: TextField(
|
||||
controller: controller,
|
||||
autofocus: true,
|
||||
decoration: InputDecoration(hintText: context.lang.reportUserReason),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: Text(context.lang.cancel),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text(context.lang.ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(controller.text);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,7 +371,6 @@ class PlanCard extends StatelessWidget {
|
|||
final yearlyPrice = getPlanPrice(planId, paidMonthly: false);
|
||||
final monthlyPrice = getPlanPrice(planId, paidMonthly: true);
|
||||
var features = <String>[];
|
||||
final isPayingUser = planId == 'Family' || planId == 'Pro';
|
||||
|
||||
switch (planId) {
|
||||
case 'Free':
|
||||
|
|
@ -419,7 +418,7 @@ class PlanCard extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
if (yearlyPrice != 0) const SizedBox(height: 10),
|
||||
if (isPayingUser)
|
||||
if (yearlyPrice != 0 && paidMonthly == null)
|
||||
Column(
|
||||
children: [
|
||||
if (paidMonthly == null || paidMonthly!)
|
||||
|
|
@ -442,7 +441,7 @@ class PlanCard extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
if (isPayingUser && paidMonthly != null)
|
||||
if (paidMonthly != null)
|
||||
Text(
|
||||
(paidMonthly!)
|
||||
? '${localePrizing(context, monthlyPrice)}/${context.lang.month}'
|
||||
|
|
|
|||
Loading…
Reference in a new issue