123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import 'package:easy_localization/easy_localization.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_hooks/flutter_hooks.dart';
- import 'package:hooks_riverpod/hooks_riverpod.dart';
- import 'package:immich_mobile/modules/asset_viewer/providers/asset_description.provider.dart';
- import 'package:immich_mobile/shared/models/asset.dart';
- import 'package:immich_mobile/shared/providers/user.provider.dart';
- import 'package:immich_mobile/shared/ui/immich_toast.dart';
- import 'package:logging/logging.dart';
- class DescriptionInput extends HookConsumerWidget {
- DescriptionInput({
- super.key,
- required this.asset,
- });
- final Asset asset;
- final Logger _log = Logger('DescriptionInput');
- @override
- Widget build(BuildContext context, WidgetRef ref) {
- final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
- final textColor = isDarkTheme ? Colors.white : Colors.black;
- final controller = useTextEditingController();
- final focusNode = useFocusNode();
- final isFocus = useState(false);
- final isTextEmpty = useState(controller.text.isEmpty);
- final descriptionProvider =
- ref.watch(assetDescriptionProvider(asset).notifier);
- final description = ref.watch(assetDescriptionProvider(asset));
- final owner = ref.watch(currentUserProvider);
- final hasError = useState(false);
- useEffect(
- () {
- controller.text = description;
- isTextEmpty.value = description.isEmpty;
- return null;
- },
- [description],
- );
- submitDescription(String description) async {
- hasError.value = false;
- try {
- await descriptionProvider.setDescription(
- description,
- );
- } catch (error, stack) {
- hasError.value = true;
- _log.severe("Error updating description $error", error, stack);
- ImmichToast.show(
- context: context,
- msg: "description_input_submit_error".tr(),
- toastType: ToastType.error,
- );
- }
- }
- Widget? suffixIcon;
- if (hasError.value) {
- suffixIcon = const Icon(Icons.warning_outlined);
- } else if (!isTextEmpty.value && isFocus.value) {
- suffixIcon = IconButton(
- onPressed: () {
- controller.clear();
- isTextEmpty.value = true;
- },
- icon: Icon(
- Icons.cancel_rounded,
- color: Colors.grey[500],
- ),
- splashRadius: 10,
- );
- }
- return TextField(
- enabled: owner?.isarId == asset.ownerId,
- focusNode: focusNode,
- onTap: () => isFocus.value = true,
- onChanged: (value) {
- isTextEmpty.value = false;
- },
- onTapOutside: (a) async {
- isFocus.value = false;
- focusNode.unfocus();
- if (description != controller.text) {
- await submitDescription(controller.text);
- }
- },
- autofocus: false,
- maxLines: null,
- keyboardType: TextInputType.multiline,
- controller: controller,
- style: const TextStyle(
- fontSize: 14,
- ),
- decoration: InputDecoration(
- hintText: 'description_input_hint_text'.tr(),
- border: InputBorder.none,
- hintStyle: TextStyle(
- fontWeight: FontWeight.normal,
- fontSize: 12,
- color: textColor.withOpacity(0.5),
- ),
- suffixIcon: suffixIcon,
- ),
- );
- }
- }
|