mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 11:18:41 +00:00
fix #308
This commit is contained in:
parent
fc2513ddba
commit
58b286526d
6 changed files with 146 additions and 60 deletions
|
|
@ -822,5 +822,8 @@
|
||||||
"dialogAskDeleteMediaFilePopTitle": "Bist du sicher, dass du dein Meisterwerk löschen möchtest?",
|
"dialogAskDeleteMediaFilePopTitle": "Bist du sicher, dass du dein Meisterwerk löschen möchtest?",
|
||||||
"dialogAskDeleteMediaFilePopDelete": "Löschen",
|
"dialogAskDeleteMediaFilePopDelete": "Löschen",
|
||||||
"allowErrorTracking": "Fehler und Crashes mit uns teilen",
|
"allowErrorTracking": "Fehler und Crashes mit uns teilen",
|
||||||
"allowErrorTrackingSubtitle": "Wenn twonly abstürzt oder Fehler auftreten, werden diese automatisch an unsere selbst gehostete Glitchtip-Instanz gemeldet. Persönliche Daten wie Nachrichten oder Bilder werden niemals hochgeladen."
|
"allowErrorTrackingSubtitle": "Wenn twonly abstürzt oder Fehler auftreten, werden diese automatisch an unsere selbst gehostete Glitchtip-Instanz gemeldet. Persönliche Daten wie Nachrichten oder Bilder werden niemals hochgeladen.",
|
||||||
|
"avatarSaveChanges": "Möchtest du die Änderungen speichern?",
|
||||||
|
"avatarSaveChangesStore": "Speichern",
|
||||||
|
"avatarSaveChangesDiscard": "Verwerfen"
|
||||||
}
|
}
|
||||||
|
|
@ -600,5 +600,8 @@
|
||||||
"dialogAskDeleteMediaFilePopTitle": "Are you sure you want to delete your masterpiece?",
|
"dialogAskDeleteMediaFilePopTitle": "Are you sure you want to delete your masterpiece?",
|
||||||
"dialogAskDeleteMediaFilePopDelete": "Delete",
|
"dialogAskDeleteMediaFilePopDelete": "Delete",
|
||||||
"allowErrorTracking": "Share errors and crashes with us",
|
"allowErrorTracking": "Share errors and crashes with us",
|
||||||
"allowErrorTrackingSubtitle": "If twonly crashes or errors occur, these are automatically reported to our self-hosted Glitchtip instance. Personal data such as messages or images are never uploaded."
|
"allowErrorTrackingSubtitle": "If twonly crashes or errors occur, these are automatically reported to our self-hosted Glitchtip instance. Personal data such as messages or images are never uploaded.",
|
||||||
|
"avatarSaveChanges": "Would you like to save the changes?",
|
||||||
|
"avatarSaveChangesStore": "Save",
|
||||||
|
"avatarSaveChangesDiscard": "Discard"
|
||||||
}
|
}
|
||||||
|
|
@ -2707,6 +2707,24 @@ abstract class AppLocalizations {
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'If twonly crashes or errors occur, these are automatically reported to our self-hosted Glitchtip instance. Personal data such as messages or images are never uploaded.'**
|
/// **'If twonly crashes or errors occur, these are automatically reported to our self-hosted Glitchtip instance. Personal data such as messages or images are never uploaded.'**
|
||||||
String get allowErrorTrackingSubtitle;
|
String get allowErrorTrackingSubtitle;
|
||||||
|
|
||||||
|
/// No description provided for @avatarSaveChanges.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Would you like to save the changes?'**
|
||||||
|
String get avatarSaveChanges;
|
||||||
|
|
||||||
|
/// No description provided for @avatarSaveChangesStore.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Save'**
|
||||||
|
String get avatarSaveChangesStore;
|
||||||
|
|
||||||
|
/// No description provided for @avatarSaveChangesDiscard.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Discard'**
|
||||||
|
String get avatarSaveChangesDiscard;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppLocalizationsDelegate
|
class _AppLocalizationsDelegate
|
||||||
|
|
|
||||||
|
|
@ -1495,4 +1495,13 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get allowErrorTrackingSubtitle =>
|
String get allowErrorTrackingSubtitle =>
|
||||||
'Wenn twonly abstürzt oder Fehler auftreten, werden diese automatisch an unsere selbst gehostete Glitchtip-Instanz gemeldet. Persönliche Daten wie Nachrichten oder Bilder werden niemals hochgeladen.';
|
'Wenn twonly abstürzt oder Fehler auftreten, werden diese automatisch an unsere selbst gehostete Glitchtip-Instanz gemeldet. Persönliche Daten wie Nachrichten oder Bilder werden niemals hochgeladen.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get avatarSaveChanges => 'Möchtest du die Änderungen speichern?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get avatarSaveChangesStore => 'Speichern';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get avatarSaveChangesDiscard => 'Verwerfen';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1485,4 +1485,13 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get allowErrorTrackingSubtitle =>
|
String get allowErrorTrackingSubtitle =>
|
||||||
'If twonly crashes or errors occur, these are automatically reported to our self-hosted Glitchtip instance. Personal data such as messages or images are never uploaded.';
|
'If twonly crashes or errors occur, these are automatically reported to our self-hosted Glitchtip instance. Personal data such as messages or images are never uploaded.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get avatarSaveChanges => 'Would you like to save the changes?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get avatarSaveChangesStore => 'Save';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get avatarSaveChangesDiscard => 'Discard';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import 'dart:math';
|
||||||
import 'package:avatar_maker/avatar_maker.dart';
|
import 'package:avatar_maker/avatar_maker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/services/api/messages.dart';
|
import 'package:twonly/src/services/api/messages.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/utils/storage.dart';
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
|
|
@ -77,69 +78,112 @@ class _ModifyAvatarState extends State<ModifyAvatar> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool?> _showBackDialog() {
|
||||||
|
return showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(
|
||||||
|
context.lang.avatarSaveChanges,
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
FilledButton(
|
||||||
|
child: Text(context.lang.avatarSaveChangesStore),
|
||||||
|
onPressed: () async {
|
||||||
|
await storeAvatarAndExit();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: Text(context.lang.avatarSaveChangesDiscard),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> storeAvatarAndExit() async {
|
||||||
|
await _avatarMakerController.saveAvatarSVG();
|
||||||
|
final json = _avatarMakerController.getJsonOptionsSync();
|
||||||
|
final svg = _avatarMakerController.getAvatarSVGSync();
|
||||||
|
await updateUserAvatar(json, svg);
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return PopScope<bool?>(
|
||||||
appBar: AppBar(
|
canPop: false,
|
||||||
title: Text(context.lang.settingsProfileCustomizeAvatar),
|
onPopInvokedWithResult: (bool didPop, bool? result) async {
|
||||||
),
|
if (didPop) return;
|
||||||
body: Center(
|
if (_avatarMakerController.getJsonOptionsSync() != gUser.avatarJson) {
|
||||||
child: SingleChildScrollView(
|
// there where changes
|
||||||
child: Column(
|
final shouldPop = await _showBackDialog() ?? false;
|
||||||
children: [
|
if (context.mounted && shouldPop) {
|
||||||
Padding(
|
Navigator.pop(context);
|
||||||
padding: EdgeInsets.zero,
|
}
|
||||||
child: AvatarMakerAvatar(
|
} else {
|
||||||
radius: 130,
|
Navigator.pop(context);
|
||||||
backgroundColor: Colors.transparent,
|
}
|
||||||
controller: _avatarMakerController,
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(context.lang.settingsProfileCustomizeAvatar),
|
||||||
|
),
|
||||||
|
body: Center(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
child: AvatarMakerAvatar(
|
||||||
|
radius: 130,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
controller: _avatarMakerController,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(
|
||||||
SizedBox(
|
child: Row(
|
||||||
child: Row(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
children: [
|
||||||
children: [
|
IconButton(
|
||||||
IconButton(
|
icon: const FaIcon(FontAwesomeIcons.floppyDisk),
|
||||||
icon: const FaIcon(FontAwesomeIcons.floppyDisk),
|
onPressed: storeAvatarAndExit,
|
||||||
onPressed: () async {
|
),
|
||||||
await _avatarMakerController.saveAvatarSVG();
|
IconButton(
|
||||||
final json =
|
icon: const FaIcon(FontAwesomeIcons.shuffle),
|
||||||
_avatarMakerController.getJsonOptionsSync();
|
onPressed:
|
||||||
final svg = _avatarMakerController.getAvatarSVGSync();
|
_avatarMakerController.randomizedSelectedOptions,
|
||||||
await updateUserAvatar(json, svg);
|
),
|
||||||
if (context.mounted) {
|
IconButton(
|
||||||
Navigator.pop(context);
|
icon: const Icon(FontAwesomeIcons.rotateLeft),
|
||||||
}
|
onLongPress: () async {
|
||||||
},
|
await PersistentAvatarMakerController
|
||||||
),
|
.clearAvatarMaker();
|
||||||
IconButton(
|
await _avatarMakerController.restoreState();
|
||||||
icon: const FaIcon(FontAwesomeIcons.shuffle),
|
},
|
||||||
onPressed:
|
onPressed: _avatarMakerController.restoreState,
|
||||||
_avatarMakerController.randomizedSelectedOptions,
|
),
|
||||||
),
|
],
|
||||||
IconButton(
|
),
|
||||||
icon: const Icon(FontAwesomeIcons.rotateLeft),
|
|
||||||
onLongPress: () async {
|
|
||||||
await PersistentAvatarMakerController
|
|
||||||
.clearAvatarMaker();
|
|
||||||
await _avatarMakerController.restoreState();
|
|
||||||
},
|
|
||||||
onPressed: _avatarMakerController.restoreState,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
Padding(
|
||||||
Padding(
|
padding:
|
||||||
padding:
|
const EdgeInsets.symmetric(horizontal: 8, vertical: 30),
|
||||||
const EdgeInsets.symmetric(horizontal: 8, vertical: 30),
|
child: AvatarMakerCustomizer(
|
||||||
child: AvatarMakerCustomizer(
|
scaffoldWidth:
|
||||||
scaffoldWidth:
|
min(600, MediaQuery.of(context).size.width * 0.85),
|
||||||
min(600, MediaQuery.of(context).size.width * 0.85),
|
theme: getAvatarMakerTheme(context),
|
||||||
theme: getAvatarMakerTheme(context),
|
controller: _avatarMakerController,
|
||||||
controller: _avatarMakerController,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue