diff --git a/lib/comment/view/create_comment_page.dart b/lib/comment/view/create_comment_page.dart index 47a519429..f0f1f404d 100644 --- a/lib/comment/view/create_comment_page.dart +++ b/lib/comment/view/create_comment_page.dart @@ -6,7 +6,6 @@ import 'dart:convert'; import 'package:flutter/material.dart'; // Package imports -import 'package:collection/collection.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; @@ -17,7 +16,6 @@ import 'package:shared_preferences/shared_preferences.dart'; // Project imports import 'package:thunder/comment/cubit/create_comment_cubit.dart'; import 'package:thunder/community/utils/post_card_action_helpers.dart'; -import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/core/enums/local_settings.dart'; import 'package:thunder/core/models/post_view_media.dart'; import 'package:thunder/core/singletons/preferences.dart'; @@ -25,6 +23,7 @@ import 'package:thunder/post/widgets/post_view.dart'; import 'package:thunder/shared/comment_content.dart'; import 'package:thunder/shared/common_markdown_body.dart'; import 'package:thunder/shared/input_dialogs.dart'; +import 'package:thunder/shared/language_selector.dart'; import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/user/widgets/user_indicator.dart'; import 'package:thunder/utils/instance.dart'; @@ -475,80 +474,6 @@ class _CreateCommentPageState extends State { } } -/// Creates a widget which displays a preview of a pre-selected language, with the ability to change the selected language -/// -/// Passing in [languageId] will set the initial state of the widget to display that given language. -/// A callback function [onLanguageSelected] will be triggered whenever a new language is selected from the dropdown. -class LanguageSelector extends StatefulWidget { - const LanguageSelector({ - super.key, - required this.languageId, - required this.onLanguageSelected, - }); - - /// The initial language id to be passed in - final int? languageId; - - /// A callback function to trigger whenever a language is selected from the dropdown - final Function(Language?) onLanguageSelected; - - @override - State createState() => _LanguageSelectorState(); -} - -class _LanguageSelectorState extends State { - late int? _languageId; - late Language? _language; - - @override - void initState() { - super.initState(); - _languageId = widget.languageId; - - // Determine the language from the languageId - List languages = context.read().state.getSiteResponse?.allLanguages ?? []; - _language = languages.firstWhereOrNull((Language language) => language.id == _languageId); - } - - @override - Widget build(BuildContext context) { - final l10n = AppLocalizations.of(context)!; - final theme = Theme.of(context); - - return Transform.translate( - offset: const Offset(-8, 0), - child: InkWell( - onTap: () { - showLanguageInputDialog( - context, - title: l10n.language, - onLanguageSelected: (language) { - if (language.id == -1) { - setState(() => _languageId = _language = null); - widget.onLanguageSelected(null); - } else { - setState(() { - _languageId = language.id; - _language = language; - }); - widget.onLanguageSelected(language); - } - }, - ); - }, - borderRadius: const BorderRadius.all(Radius.circular(50)), - child: Padding( - padding: const EdgeInsets.only(left: 8, top: 12, bottom: 12), - child: Text( - '${l10n.language}: ${_language?.name ?? l10n.selectLanguage}', - style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600), - ), - ), - ), - ); - } -} - class DraftComment { String? text; bool saveAsDraft = true; diff --git a/lib/community/pages/create_post_page.dart b/lib/community/pages/create_post_page.dart index b45c26ed7..1e6c5e5c2 100644 --- a/lib/community/pages/create_post_page.dart +++ b/lib/community/pages/create_post_page.dart @@ -1,19 +1,22 @@ +// Dart imports import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:collection/collection.dart'; +// Flutter imports import 'package:flutter/material.dart'; + +// Package imports import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart'; import 'package:lemmy_api_client/v3.dart'; import 'package:link_preview_generator/link_preview_generator.dart'; - -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:markdown_editor/markdown_editor.dart'; import 'package:shared_preferences/shared_preferences.dart'; +// Project imports import 'package:thunder/account/models/account.dart'; import 'package:thunder/community/bloc/image_bloc.dart'; import 'package:thunder/community/utils/post_card_action_helpers.dart'; @@ -25,18 +28,19 @@ import 'package:thunder/core/models/post_view_media.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; import 'package:thunder/core/singletons/preferences.dart'; import 'package:thunder/post/cubit/create_post_cubit.dart'; -import 'package:thunder/shared/common_markdown_body.dart'; import 'package:thunder/shared/avatars/community_avatar.dart'; +import 'package:thunder/shared/common_markdown_body.dart'; import 'package:thunder/shared/cross_posts.dart'; import 'package:thunder/shared/full_name_widgets.dart'; import 'package:thunder/shared/input_dialogs.dart'; +import 'package:thunder/shared/language_selector.dart'; import 'package:thunder/shared/link_preview_card.dart'; import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/user/utils/restore_user.dart'; import 'package:thunder/user/widgets/user_selector.dart'; import 'package:thunder/utils/debounce.dart'; -import 'package:thunder/utils/media/image.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/media/image.dart'; class CreatePostPage extends StatefulWidget { final int? communityId; @@ -488,7 +492,8 @@ class _CreatePostPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded( + ConstrainedBox( + constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.60), child: LanguageSelector( languageId: languageId, onLanguageSelected: (Language? language) { @@ -496,10 +501,11 @@ class _CreatePostPageState extends State { }, ), ), - Row( + Wrap( + crossAxisAlignment: WrapCrossAlignment.center, children: [ - Text(l10n.postNSFW), - const SizedBox(width: 10), + Text(l10n.nsfw), + const SizedBox(width: 4.0), Switch( value: isNSFW, onChanged: (bool value) => setState(() => isNSFW = value), @@ -656,80 +662,6 @@ class _CreatePostPageState extends State { } } -/// Creates a widget which displays a preview of a pre-selected language, with the ability to change the selected language -/// -/// Passing in [languageId] will set the initial state of the widget to display that given language. -/// A callback function [onLanguageSelected] will be triggered whenever a new language is selected from the dropdown. -class LanguageSelector extends StatefulWidget { - const LanguageSelector({ - super.key, - required this.languageId, - required this.onLanguageSelected, - }); - - /// The initial language id to be passed in - final int? languageId; - - /// A callback function to trigger whenever a language is selected from the dropdown - final Function(Language?) onLanguageSelected; - - @override - State createState() => _LanguageSelectorState(); -} - -class _LanguageSelectorState extends State { - late int? _languageId; - late Language? _language; - - @override - void initState() { - super.initState(); - _languageId = widget.languageId; - - // Determine the language from the languageId - List languages = context.read().state.getSiteResponse?.allLanguages ?? []; - _language = languages.firstWhereOrNull((Language language) => language.id == _languageId); - } - - @override - Widget build(BuildContext context) { - final l10n = AppLocalizations.of(context)!; - final theme = Theme.of(context); - - return Transform.translate( - offset: const Offset(-8, 0), - child: InkWell( - onTap: () { - showLanguageInputDialog( - context, - title: l10n.language, - onLanguageSelected: (language) { - if (language.id == -1) { - setState(() => _languageId = _language = null); - widget.onLanguageSelected(null); - } else { - setState(() { - _languageId = language.id; - _language = language; - }); - widget.onLanguageSelected(language); - } - }, - ); - }, - borderRadius: const BorderRadius.all(Radius.circular(50)), - child: Padding( - padding: const EdgeInsets.only(left: 8, top: 12, bottom: 12), - child: Text( - '${l10n.language}: ${_language?.name ?? l10n.selectLanguage}', - style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600), - ), - ), - ), - ); - } -} - /// Creates a widget which displays a preview of a pre-selected community, with the ability to change the selected community /// /// Passing in either [communityId] or [communityView] will set the initial state of the widget to display that given community. diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a05803518..0556d8312 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1113,6 +1113,10 @@ "@notificationsWarningDialog": { "description": "The content of the warning dialog for the notifications feature" }, + "nsfw": "NSFW", + "@nsfw": { + "description": "Short description for NSFW label" + }, "nsfwWarning": "NSFW - Tap to reveal", "@nsfwWarning": { "description": "Warning for NSFW posts" @@ -1481,7 +1485,7 @@ "@selectCommunity": {}, "selectFeedType": "Select Feed Type", "@selectFeedType": {}, - "selectLanguage": "Select language", + "selectLanguage": "Select Language", "@selectLanguage": { "description": "The prompt to select a language in the post creation page" }, diff --git a/lib/shared/language_selector.dart b/lib/shared/language_selector.dart new file mode 100644 index 000000000..b620772c2 --- /dev/null +++ b/lib/shared/language_selector.dart @@ -0,0 +1,95 @@ +// Flutter imports +import 'package:flutter/material.dart'; + +// Package imports +import 'package:collection/collection.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:lemmy_api_client/v3.dart'; + +// Project imports +import 'package:thunder/core/auth/bloc/auth_bloc.dart'; +import 'package:thunder/shared/input_dialogs.dart'; + +/// Creates a widget which displays a preview of a pre-selected language, with the ability to change the selected language +/// +/// Passing in [languageId] will set the initial state of the widget to display that given language. +/// A callback function [onLanguageSelected] will be triggered whenever a new language is selected from the dropdown. +class LanguageSelector extends StatefulWidget { + const LanguageSelector({ + super.key, + required this.languageId, + required this.onLanguageSelected, + }); + + /// The initial language id to be passed in + final int? languageId; + + /// A callback function to trigger whenever a language is selected from the dropdown + final Function(Language?) onLanguageSelected; + + @override + State createState() => _LanguageSelectorState(); +} + +class _LanguageSelectorState extends State { + late int? _languageId; + late Language? _language; + + @override + void initState() { + super.initState(); + _languageId = widget.languageId; + + // Determine the language from the languageId + List languages = context.read().state.getSiteResponse?.allLanguages ?? []; + _language = languages.firstWhereOrNull((Language language) => language.id == _languageId); + } + + @override + Widget build(BuildContext context) { + final l10n = AppLocalizations.of(context)!; + final theme = Theme.of(context); + + return Transform.translate( + offset: const Offset(-8, 0), + child: InkWell( + onTap: () { + showLanguageInputDialog( + context, + title: l10n.language, + onLanguageSelected: (language) { + if (language.id == -1) { + setState(() => _languageId = _language = null); + widget.onLanguageSelected(null); + } else { + setState(() { + _languageId = language.id; + _language = language; + }); + widget.onLanguageSelected(language); + } + }, + ); + }, + borderRadius: const BorderRadius.all(Radius.circular(50)), + child: Padding( + padding: const EdgeInsets.only(left: 8, right: 8, top: 12, bottom: 12), + child: Text.rich( + softWrap: true, + TextSpan( + children: [ + TextSpan(text: _language != null ? '${l10n.language}: ${_language?.name}' : l10n.selectLanguage), + const WidgetSpan( + alignment: PlaceholderAlignment.middle, + child: Icon(Icons.chevron_right_rounded), + ), + ], + style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600), + ), + ), + ), + ), + ); + } +}