mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 13:08:42 +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
|
## 0.0.58
|
||||||
|
|
||||||
- twonly now has a free plan and is now financed by donations and an optional subscription with more features (coming soon)
|
- 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
|
- iOS gestures to close images
|
||||||
- Improved the chat messages view, including better citation view and display times.
|
- Improved chat messages view, including better citation view and display times
|
||||||
- Updated onboarding screens and simplified the registration view
|
- onboarding screens updated and registration view simplified
|
||||||
- The sender is displayed in the top right corner when a media file is opened.
|
- The sender is displayed in the top right corner when a media file is opened
|
||||||
- Images are now stored as WebP to save storage
|
- Images are now stored as WebP to save storage
|
||||||
|
- Button to report users
|
||||||
- Multiple bug fixes
|
- Multiple bug fixes
|
||||||
|
|
@ -219,6 +219,9 @@ String getContactDisplayName(Contact user) {
|
||||||
if (user.deleted) {
|
if (user.deleted) {
|
||||||
name = applyStrikethrough(name);
|
name = applyStrikethrough(name);
|
||||||
}
|
}
|
||||||
|
if (name.length > 12) {
|
||||||
|
return '${name.substring(0, 12)} ...';
|
||||||
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -331,5 +331,8 @@
|
||||||
"doubleClickToReopen": "Doppelklicken zum\nerneuten Öffnen.",
|
"doubleClickToReopen": "Doppelklicken zum\nerneuten Öffnen.",
|
||||||
"retransmissionRequested": "Wird erneut versucht.",
|
"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!",
|
"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",
|
"doubleClickToReopen": "Double-click\nto open again",
|
||||||
"retransmissionRequested": "Retransmission requested",
|
"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!",
|
"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:
|
/// In en, this message translates to:
|
||||||
/// **'Open changelog automatically'**
|
/// **'Open changelog automatically'**
|
||||||
String get openChangeLog;
|
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
|
class _AppLocalizationsDelegate
|
||||||
|
|
|
||||||
|
|
@ -1076,4 +1076,15 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get openChangeLog => 'Changelog automatisch öffnen';
|
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
|
@override
|
||||||
String get openChangeLog => 'Open changelog automatically';
|
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': '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': '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': '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': [
|
'8': [
|
||||||
{'1': 'ApplicationData'},
|
{'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')
|
@$core.Deprecated('Use applicationDataDescriptor instead')
|
||||||
const ApplicationData_DeleteAccount$json = {
|
const ApplicationData_DeleteAccount$json = {
|
||||||
'1': 'DeleteAccount',
|
'1': 'DeleteAccount',
|
||||||
|
|
@ -351,26 +361,29 @@ final $typed_data.Uint8List applicationDataDescriptor = $convert.base64Decode(
|
||||||
'cHJla2V5Ynl1c2VyaWQSZgoSdXBkYXRlc2lnbmVkcHJla2V5GBcgASgLMjQuY2xpZW50X3RvX3'
|
'cHJla2V5Ynl1c2VyaWQSZgoSdXBkYXRlc2lnbmVkcHJla2V5GBcgASgLMjQuY2xpZW50X3RvX3'
|
||||||
'NlcnZlci5BcHBsaWNhdGlvbkRhdGEuVXBkYXRlU2lnbmVkUHJlS2V5SABSEnVwZGF0ZXNpZ25l'
|
'NlcnZlci5BcHBsaWNhdGlvbkRhdGEuVXBkYXRlU2lnbmVkUHJlS2V5SABSEnVwZGF0ZXNpZ25l'
|
||||||
'ZHByZWtleRJXCg1kZWxldGVhY2NvdW50GBggASgLMi8uY2xpZW50X3RvX3NlcnZlci5BcHBsaW'
|
'ZHByZWtleRJXCg1kZWxldGVhY2NvdW50GBggASgLMi8uY2xpZW50X3RvX3NlcnZlci5BcHBsaW'
|
||||||
'NhdGlvbkRhdGEuRGVsZXRlQWNjb3VudEgAUg1kZWxldGVhY2NvdW50GmoKC1RleHRNZXNzYWdl'
|
'NhdGlvbkRhdGEuRGVsZXRlQWNjb3VudEgAUg1kZWxldGVhY2NvdW50Ek4KCnJlcG9ydHVzZXIY'
|
||||||
'EhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBISCgRib2R5GAMgASgMUgRib2R5EiAKCXB1c2hfZG'
|
'GSABKAsyLC5jbGllbnRfdG9fc2VydmVyLkFwcGxpY2F0aW9uRGF0YS5SZXBvcnRVc2VySABSCn'
|
||||||
'F0YRgEIAEoDEgAUghwdXNoRGF0YYgBAUIMCgpfcHVzaF9kYXRhGi8KEUdldFVzZXJCeVVzZXJu'
|
'JlcG9ydHVzZXIaagoLVGV4dE1lc3NhZ2USFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkEhIKBGJv'
|
||||||
'YW1lEhoKCHVzZXJuYW1lGAEgASgJUgh1c2VybmFtZRo1ChRVcGRhdGVHb29nbGVGY21Ub2tlbh'
|
'ZHkYAyABKAxSBGJvZHkSIAoJcHVzaF9kYXRhGAQgASgMSABSCHB1c2hEYXRhiAEBQgwKCl9wdX'
|
||||||
'IdCgpnb29nbGVfZmNtGAEgASgJUglnb29nbGVGY20aJgoLR2V0VXNlckJ5SWQSFwoHdXNlcl9p'
|
'NoX2RhdGEaLwoRR2V0VXNlckJ5VXNlcm5hbWUSGgoIdXNlcm5hbWUYASABKAlSCHVzZXJuYW1l'
|
||||||
'ZBgBIAEoA1IGdXNlcklkGikKDVJlZGVlbVZvdWNoZXISGAoHdm91Y2hlchgBIAEoCVIHdm91Y2'
|
'GjUKFFVwZGF0ZUdvb2dsZUZjbVRva2VuEh0KCmdvb2dsZV9mY20YASABKAlSCWdvb2dsZUZjbR'
|
||||||
'hlchpwChFTd2l0Y2hUb1BheWVkUGxhbhIXCgdwbGFuX2lkGAEgASgJUgZwbGFuSWQSHwoLcGF5'
|
'omCgtHZXRVc2VyQnlJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQaKQoNUmVkZWVtVm91Y2hl'
|
||||||
'X21vbnRobHkYAiABKAhSCnBheU1vbnRobHkSIQoMYXV0b19yZW5ld2FsGAMgASgIUgthdXRvUm'
|
'chIYCgd2b3VjaGVyGAEgASgJUgd2b3VjaGVyGnAKEVN3aXRjaFRvUGF5ZWRQbGFuEhcKB3BsYW'
|
||||||
'VuZXdhbBo2ChFVcGRhdGVQbGFuT3B0aW9ucxIhCgxhdXRvX3JlbmV3YWwYASABKAhSC2F1dG9S'
|
'5faWQYASABKAlSBnBsYW5JZBIfCgtwYXlfbW9udGhseRgCIAEoCFIKcGF5TW9udGhseRIhCgxh'
|
||||||
'ZW5ld2FsGjAKDUNyZWF0ZVZvdWNoZXISHwoLdmFsdWVfY2VudHMYASABKA1SCnZhbHVlQ2VudH'
|
'dXRvX3JlbmV3YWwYAyABKAhSC2F1dG9SZW5ld2FsGjYKEVVwZGF0ZVBsYW5PcHRpb25zEiEKDG'
|
||||||
'MaDQoLR2V0TG9jYXRpb24aDQoLR2V0Vm91Y2hlcnMaEwoRR2V0QXZhaWxhYmxlUGxhbnMaFwoV'
|
'F1dG9fcmVuZXdhbBgBIAEoCFILYXV0b1JlbmV3YWwaMAoNQ3JlYXRlVm91Y2hlchIfCgt2YWx1'
|
||||||
'R2V0QWRkQWNjb3VudHNJbnZpdGVzGhUKE0dldEN1cnJlbnRQbGFuSW5mb3MaNwoUUmVkZWVtQW'
|
'ZV9jZW50cxgBIAEoDVIKdmFsdWVDZW50cxoNCgtHZXRMb2NhdGlvbhoNCgtHZXRWb3VjaGVycx'
|
||||||
'RkaXRpb25hbENvZGUSHwoLaW52aXRlX2NvZGUYAiABKAlSCmludml0ZUNvZGUaLwoUUmVtb3Zl'
|
'oTChFHZXRBdmFpbGFibGVQbGFucxoXChVHZXRBZGRBY2NvdW50c0ludml0ZXMaFQoTR2V0Q3Vy'
|
||||||
'QWRkaXRpb25hbFVzZXISFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkGi0KEkdldFByZWtleXNCeV'
|
'cmVudFBsYW5JbmZvcxo3ChRSZWRlZW1BZGRpdGlvbmFsQ29kZRIfCgtpbnZpdGVfY29kZRgCIA'
|
||||||
'VzZXJJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQaMgoXR2V0U2lnbmVkUHJlS2V5QnlVc2Vy'
|
'EoCVIKaW52aXRlQ29kZRovChRSZW1vdmVBZGRpdGlvbmFsVXNlchIXCgd1c2VyX2lkGAEgASgD'
|
||||||
'SWQSFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkGpsBChJVcGRhdGVTaWduZWRQcmVLZXkSKAoQc2'
|
'UgZ1c2VySWQaLQoSR2V0UHJla2V5c0J5VXNlcklkEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZB'
|
||||||
'lnbmVkX3ByZWtleV9pZBgBIAEoA1IOc2lnbmVkUHJla2V5SWQSIwoNc2lnbmVkX3ByZWtleRgC'
|
'oyChdHZXRTaWduZWRQcmVLZXlCeVVzZXJJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQamwEK'
|
||||||
'IAEoDFIMc2lnbmVkUHJla2V5EjYKF3NpZ25lZF9wcmVrZXlfc2lnbmF0dXJlGAMgASgMUhVzaW'
|
'ElVwZGF0ZVNpZ25lZFByZUtleRIoChBzaWduZWRfcHJla2V5X2lkGAEgASgDUg5zaWduZWRQcm'
|
||||||
'duZWRQcmVrZXlTaWduYXR1cmUaNQoMRG93bmxvYWREb25lEiUKDmRvd25sb2FkX3Rva2VuGAEg'
|
'VrZXlJZBIjCg1zaWduZWRfcHJla2V5GAIgASgMUgxzaWduZWRQcmVrZXkSNgoXc2lnbmVkX3By'
|
||||||
'ASgMUg1kb3dubG9hZFRva2VuGg8KDURlbGV0ZUFjY291bnRCEQoPQXBwbGljYXRpb25EYXRh');
|
'ZWtleV9zaWduYXR1cmUYAyABKAxSFXNpZ25lZFByZWtleVNpZ25hdHVyZRo1CgxEb3dubG9hZE'
|
||||||
|
'RvbmUSJQoOZG93bmxvYWRfdG9rZW4YASABKAxSDWRvd25sb2FkVG9rZW4aTgoKUmVwb3J0VXNl'
|
||||||
|
'chIoChByZXBvcnRlZF91c2VyX2lkGAEgASgDUg5yZXBvcnRlZFVzZXJJZBIWCgZyZWFzb24YAi'
|
||||||
|
'ABKAlSBnJlYXNvbhoPCg1EZWxldGVBY2NvdW50QhEKD0FwcGxpY2F0aW9uRGF0YQ==');
|
||||||
|
|
||||||
@$core.Deprecated('Use responseDescriptor instead')
|
@$core.Deprecated('Use responseDescriptor instead')
|
||||||
const Response$json = {
|
const Response$json = {
|
||||||
|
|
|
||||||
|
|
@ -576,6 +576,15 @@ class ApiService {
|
||||||
return sendRequestSync(req);
|
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 {
|
Future<Result> deleteAccount() async {
|
||||||
final get = ApplicationData_DeleteAccount();
|
final get = ApplicationData_DeleteAccount();
|
||||||
final appData = ApplicationData()..deleteaccount = get;
|
final appData = ApplicationData()..deleteaccount = get;
|
||||||
|
|
|
||||||
|
|
@ -317,10 +317,10 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
widget.selectedCameraDetails.scaleFactor =
|
widget.selectedCameraDetails.scaleFactor = (baseScaleFactor +
|
||||||
// ignore: avoid_dynamic_calls
|
// ignore: avoid_dynamic_calls
|
||||||
(baseScaleFactor + (basePanY - (details.localPosition.dy as int)) / 30)
|
(basePanY - (details.localPosition.dy as double)) / 30)
|
||||||
.clamp(1, widget.selectedCameraDetails.maxAvailableZoom);
|
.clamp(1, widget.selectedCameraDetails.maxAvailableZoom);
|
||||||
|
|
||||||
await widget.cameraController!
|
await widget.cameraController!
|
||||||
.setZoomLevel(widget.selectedCameraDetails.scaleFactor);
|
.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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final contact = twonlyDB.contactsDao
|
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(
|
BetterListTile(
|
||||||
icon: FontAwesomeIcons.ban,
|
icon: FontAwesomeIcons.ban,
|
||||||
color: Colors.red,
|
|
||||||
text: context.lang.contactBlock,
|
text: context.lang.contactBlock,
|
||||||
onTap: () => handleUserBlockRequest(contact),
|
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 yearlyPrice = getPlanPrice(planId, paidMonthly: false);
|
||||||
final monthlyPrice = getPlanPrice(planId, paidMonthly: true);
|
final monthlyPrice = getPlanPrice(planId, paidMonthly: true);
|
||||||
var features = <String>[];
|
var features = <String>[];
|
||||||
final isPayingUser = planId == 'Family' || planId == 'Pro';
|
|
||||||
|
|
||||||
switch (planId) {
|
switch (planId) {
|
||||||
case 'Free':
|
case 'Free':
|
||||||
|
|
@ -419,7 +418,7 @@ class PlanCard extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (yearlyPrice != 0) const SizedBox(height: 10),
|
if (yearlyPrice != 0) const SizedBox(height: 10),
|
||||||
if (isPayingUser)
|
if (yearlyPrice != 0 && paidMonthly == null)
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
if (paidMonthly == null || paidMonthly!)
|
if (paidMonthly == null || paidMonthly!)
|
||||||
|
|
@ -442,7 +441,7 @@ class PlanCard extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (isPayingUser && paidMonthly != null)
|
if (paidMonthly != null)
|
||||||
Text(
|
Text(
|
||||||
(paidMonthly!)
|
(paidMonthly!)
|
||||||
? '${localePrizing(context, monthlyPrice)}/${context.lang.month}'
|
? '${localePrizing(context, monthlyPrice)}/${context.lang.month}'
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue