mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-03 19:54:12 +00:00 
			
		
		
		
	Can upload new custom emojies
This commit is contained in:
		@@ -4,6 +4,7 @@ import 'package:comunic/enums/user_page_visibility.dart';
 | 
			
		||||
import 'package:comunic/models/account_image_settings.dart';
 | 
			
		||||
import 'package:comunic/models/api_request.dart';
 | 
			
		||||
import 'package:comunic/models/general_settings.dart';
 | 
			
		||||
import 'package:comunic/models/new_emoji.dart';
 | 
			
		||||
 | 
			
		||||
/// Settings helper
 | 
			
		||||
///
 | 
			
		||||
@@ -123,4 +124,14 @@ class SettingsHelper {
 | 
			
		||||
      (await APIRequest(uri: "settings/delete_account_image", needLogin: true)
 | 
			
		||||
              .exec())
 | 
			
		||||
          .isOK;
 | 
			
		||||
 | 
			
		||||
  /// Upload a new emoji
 | 
			
		||||
  static Future<void> uploadNewCustomEmoji(NewEmoji newEmoji) async =>
 | 
			
		||||
      (await APIRequest(
 | 
			
		||||
                  uri: "settings/upload_custom_emoji",
 | 
			
		||||
                  needLogin: true,
 | 
			
		||||
                  args: {"shortcut": newEmoji.shortcut})
 | 
			
		||||
              .addFile("image", newEmoji.image)
 | 
			
		||||
              .execWithFiles())
 | 
			
		||||
          .assertOk();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,8 @@ class UsersHelper {
 | 
			
		||||
  /// of failure
 | 
			
		||||
  Future<UsersList> getListWithThrow(Set<int> users,
 | 
			
		||||
      {bool forceDownload = false}) async {
 | 
			
		||||
    final list = await getUsersInfo(users.toList());
 | 
			
		||||
    final list =
 | 
			
		||||
        await getUsersInfo(users.toList(), forceDownload: forceDownload);
 | 
			
		||||
 | 
			
		||||
    if (list == null)
 | 
			
		||||
      throw Exception(
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								lib/models/new_emoji.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								lib/models/new_emoji.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
import 'dart:io';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
/// New emoji information
 | 
			
		||||
///
 | 
			
		||||
/// @author Pierre HUBERT
 | 
			
		||||
 | 
			
		||||
class NewEmoji {
 | 
			
		||||
  final String shortcut;
 | 
			
		||||
  final File image;
 | 
			
		||||
 | 
			
		||||
  const NewEmoji({
 | 
			
		||||
    @required this.shortcut,
 | 
			
		||||
    @required this.image,
 | 
			
		||||
  })  : assert(shortcut != null),
 | 
			
		||||
        assert(image != null);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +1,16 @@
 | 
			
		||||
import 'dart:io';
 | 
			
		||||
 | 
			
		||||
import 'package:comunic/helpers/settings_helper.dart';
 | 
			
		||||
import 'package:comunic/helpers/users_helper.dart';
 | 
			
		||||
import 'package:comunic/models/new_emoji.dart';
 | 
			
		||||
import 'package:comunic/models/user.dart';
 | 
			
		||||
import 'package:comunic/ui/widgets/async_screen_widget.dart';
 | 
			
		||||
import 'package:comunic/ui/widgets/network_image_widget.dart';
 | 
			
		||||
import 'package:comunic/utils/account_utils.dart';
 | 
			
		||||
import 'package:comunic/utils/files_utils.dart';
 | 
			
		||||
import 'package:comunic/utils/input_utils.dart';
 | 
			
		||||
import 'package:comunic/utils/intl_utils.dart';
 | 
			
		||||
import 'package:comunic/utils/ui_utils.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
/// Emojies account settings
 | 
			
		||||
@@ -30,6 +37,8 @@ class _EmojiesAccountBody extends StatefulWidget {
 | 
			
		||||
class __EmojiesAccountBodyState extends State<_EmojiesAccountBody> {
 | 
			
		||||
  User _user;
 | 
			
		||||
 | 
			
		||||
  final _key = GlobalKey<AsyncScreenWidgetState>();
 | 
			
		||||
 | 
			
		||||
  Future<void> _reload() async {
 | 
			
		||||
    _user = await UsersHelper().getSingleWithThrow(
 | 
			
		||||
      userID(),
 | 
			
		||||
@@ -40,13 +49,21 @@ class __EmojiesAccountBodyState extends State<_EmojiesAccountBody> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return AsyncScreenWidget(
 | 
			
		||||
      key: _key,
 | 
			
		||||
      onReload: _reload,
 | 
			
		||||
      onBuild: _buildSettings,
 | 
			
		||||
      errorMessage: tr("Could not refresh user information!"),
 | 
			
		||||
      showOldDataWhileUpdating: true,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildSettings() {
 | 
			
		||||
    return Stack(
 | 
			
		||||
      children: [_buildList(), _buildAddButton()],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildList() {
 | 
			
		||||
    return ListView(
 | 
			
		||||
        children: _user.customEmojies
 | 
			
		||||
            .map((u) => ListTile(
 | 
			
		||||
@@ -55,4 +72,114 @@ class __EmojiesAccountBodyState extends State<_EmojiesAccountBody> {
 | 
			
		||||
                ))
 | 
			
		||||
            .toList());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildAddButton() {
 | 
			
		||||
    return Positioned(
 | 
			
		||||
      child: FloatingActionButton(
 | 
			
		||||
        onPressed: _addEmoji,
 | 
			
		||||
        child: Icon(Icons.add),
 | 
			
		||||
      ),
 | 
			
		||||
      right: 20,
 | 
			
		||||
      bottom: 20,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Add a custom emoji
 | 
			
		||||
  void _addEmoji() async {
 | 
			
		||||
    try {
 | 
			
		||||
      final newEmoji = await showDialog<NewEmoji>(
 | 
			
		||||
        context: context,
 | 
			
		||||
        builder: (c) => _NewEmojiDialog(),
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      await SettingsHelper.uploadNewCustomEmoji(newEmoji);
 | 
			
		||||
    } catch (e, stack) {
 | 
			
		||||
      print("Could not add a new emoji: $e\n$stack");
 | 
			
		||||
      showSimpleSnack(context, tr("Could not upload emoji!"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _key.currentState.refresh();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _NewEmojiDialog extends StatefulWidget {
 | 
			
		||||
  @override
 | 
			
		||||
  __NewEmojiDialogState createState() => __NewEmojiDialogState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class __NewEmojiDialogState extends State<_NewEmojiDialog> {
 | 
			
		||||
  final _controller = TextEditingController();
 | 
			
		||||
  File _file;
 | 
			
		||||
 | 
			
		||||
  bool get _hasImage => _file != null;
 | 
			
		||||
 | 
			
		||||
  String get _shortcut => _controller.text;
 | 
			
		||||
 | 
			
		||||
  bool get _shortcutValid =>
 | 
			
		||||
      _shortcut.isNotEmpty && validateShortcut(_shortcut);
 | 
			
		||||
 | 
			
		||||
  bool get _valid => _hasImage && _shortcutValid;
 | 
			
		||||
 | 
			
		||||
  NewEmoji get _emoji => NewEmoji(shortcut: _shortcut, image: _file);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return AlertDialog(
 | 
			
		||||
      title: Text(tr("Add new emoji")),
 | 
			
		||||
      content: ConstrainedBox(
 | 
			
		||||
        constraints:
 | 
			
		||||
            BoxConstraints(maxHeight: MediaQuery.of(context).size.height - 50),
 | 
			
		||||
        child: SingleChildScrollView(
 | 
			
		||||
          child: _buildBody(),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
      actions: <Widget>[
 | 
			
		||||
        MaterialButton(
 | 
			
		||||
          onPressed: () => Navigator.of(context).pop(),
 | 
			
		||||
          child: Text(tr("Cancel").toUpperCase()),
 | 
			
		||||
        ),
 | 
			
		||||
        MaterialButton(
 | 
			
		||||
          onPressed: _valid ? () => Navigator.of(context).pop(_emoji) : null,
 | 
			
		||||
          child: Text(tr("Add").toUpperCase()),
 | 
			
		||||
        ),
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildBody() {
 | 
			
		||||
    return Column(
 | 
			
		||||
      children: <Widget>[
 | 
			
		||||
        TextField(
 | 
			
		||||
          controller: _controller,
 | 
			
		||||
          onChanged: (s) => setState(() {}),
 | 
			
		||||
          decoration: InputDecoration(
 | 
			
		||||
            alignLabelWithHint: true,
 | 
			
		||||
            labelText: tr("Shortcut"),
 | 
			
		||||
            hintText: tr(":yourShortcut:"),
 | 
			
		||||
            errorText: _shortcut.isNotEmpty && !_shortcutValid
 | 
			
		||||
                ? tr("Invalid shortcut!")
 | 
			
		||||
                : null,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
        MaterialButton(
 | 
			
		||||
          onPressed: _pickImage,
 | 
			
		||||
          child: Text(_hasImage ? tr("Replace image") : tr("Add image")),
 | 
			
		||||
        )
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void _pickImage() async {
 | 
			
		||||
    try {
 | 
			
		||||
      final image = await pickImage(context);
 | 
			
		||||
 | 
			
		||||
      if (image == null) return;
 | 
			
		||||
 | 
			
		||||
      setState(() {
 | 
			
		||||
        _file = image;
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e, stack) {
 | 
			
		||||
      print("Could not pick an image! $e\n$stack");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -31,3 +31,7 @@ bool validateUrl(String url) {
 | 
			
		||||
/// Validate directory reference
 | 
			
		||||
bool validateDirectoryReference(String ref) =>
 | 
			
		||||
    RegExp(r'@[a-zA-Z0-9]+').hasMatch(ref);
 | 
			
		||||
 | 
			
		||||
/// Validated a shortcut
 | 
			
		||||
bool validateShortcut(String shortcut) =>
 | 
			
		||||
    RegExp(r'^:[a-zA-Z0-9]+:$').hasMatch(shortcut);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user