♻️ Refactored using controller as post editing
This commit is contained in:
@ -35,6 +35,7 @@ class AccountImage extends StatelessWidget {
|
||||
UniversalImage.provider(url),
|
||||
width: ((radius ?? 20) * devicePixelRatio * 2).round(),
|
||||
height: ((radius ?? 20) * devicePixelRatio * 2).round(),
|
||||
policy: ResizeImagePolicy.fit,
|
||||
)
|
||||
: null,
|
||||
child: (content?.isEmpty ?? true)
|
||||
|
@ -1,15 +1,13 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cross_file/cross_file.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_context_menu/flutter_context_menu.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:surface/controllers/post_write_controller.dart';
|
||||
|
||||
class PostMediaPendingList extends StatelessWidget {
|
||||
final List<XFile> data;
|
||||
final List<PostWriteMedia> data;
|
||||
final Function(int idx)? onRemove;
|
||||
const PostMediaPendingList({
|
||||
super.key,
|
||||
@ -19,6 +17,8 @@ class PostMediaPendingList extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
|
||||
|
||||
return Container(
|
||||
constraints: const BoxConstraints(maxHeight: 120),
|
||||
child: ListView.separated(
|
||||
@ -53,9 +53,25 @@ class PostMediaPendingList extends StatelessWidget {
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: kIsWeb
|
||||
? Image.network(file.path, fit: BoxFit.cover)
|
||||
: Image.file(File(file.path), fit: BoxFit.cover),
|
||||
child: switch (file.type) {
|
||||
PostWriteMediaType.image =>
|
||||
LayoutBuilder(builder: (context, constraints) {
|
||||
return Image(
|
||||
image: file.getImageProvider(
|
||||
context,
|
||||
width: (constraints.maxWidth * devicePixelRatio)
|
||||
.round(),
|
||||
height: (constraints.maxHeight * devicePixelRatio)
|
||||
.round(),
|
||||
)!,
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
}),
|
||||
_ => Container(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: const Icon(Symbols.docs).center(),
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -1,87 +1,130 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:surface/controllers/post_write_controller.dart';
|
||||
|
||||
class PostMetaResult {
|
||||
final String title;
|
||||
final String description;
|
||||
class PostMetaEditor extends StatelessWidget {
|
||||
final PostWriteController controller;
|
||||
const PostMetaEditor({super.key, required this.controller});
|
||||
|
||||
PostMetaResult({required this.title, required this.description});
|
||||
}
|
||||
|
||||
class PostMetaEditor extends StatefulWidget {
|
||||
final String? initialTitle;
|
||||
final String? initialDescription;
|
||||
const PostMetaEditor({super.key, this.initialTitle, this.initialDescription});
|
||||
|
||||
@override
|
||||
State<PostMetaEditor> createState() => _PostMetaEditorState();
|
||||
}
|
||||
|
||||
class _PostMetaEditorState extends State<PostMetaEditor> {
|
||||
final TextEditingController _titleController = TextEditingController();
|
||||
final TextEditingController _descriptionController = TextEditingController();
|
||||
|
||||
void _applyChanges() {
|
||||
Navigator.pop(
|
||||
context,
|
||||
PostMetaResult(
|
||||
title: _titleController.text,
|
||||
description: _descriptionController.text,
|
||||
Future<DateTime?> _selectDate(
|
||||
BuildContext context, {
|
||||
DateTime? initialDateTime,
|
||||
}) async {
|
||||
DateTime? picked;
|
||||
await showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (BuildContext context) => Container(
|
||||
height: 216,
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
margin: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context).viewInsets.bottom,
|
||||
),
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: CupertinoDatePicker(
|
||||
initialDateTime: initialDateTime,
|
||||
mode: CupertinoDatePickerMode.dateAndTime,
|
||||
use24hFormat: true,
|
||||
onDateTimeChanged: (DateTime newDate) {
|
||||
picked = newDate;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_titleController.text = widget.initialTitle ?? '';
|
||||
_descriptionController.text = widget.initialDescription ?? '';
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_titleController.dispose();
|
||||
_descriptionController.dispose();
|
||||
super.dispose();
|
||||
return picked;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
TextField(
|
||||
controller: _titleController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'fieldPostTitle'.tr(),
|
||||
border: UnderlineInputBorder(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(4),
|
||||
TextField(
|
||||
controller: _descriptionController,
|
||||
maxLines: null,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'fieldPostDescription'.tr(),
|
||||
border: UnderlineInputBorder(),
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
const Gap(12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
final dateFormatter = DateFormat('y/M/d HH:mm:ss');
|
||||
return ListenableBuilder(
|
||||
listenable: controller,
|
||||
builder: (context, _) {
|
||||
return Column(
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: _applyChanges,
|
||||
icon: const Icon(Symbols.save),
|
||||
label: Text('apply').tr(),
|
||||
TextField(
|
||||
controller: controller.titleController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'fieldPostTitle'.tr(),
|
||||
border: UnderlineInputBorder(),
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
).padding(horizontal: 24),
|
||||
if (controller.mode == 'article') const Gap(4),
|
||||
if (controller.mode == 'article')
|
||||
TextField(
|
||||
controller: controller.descriptionController,
|
||||
maxLines: null,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'fieldPostDescription'.tr(),
|
||||
border: UnderlineInputBorder(),
|
||||
),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
).padding(horizontal: 24),
|
||||
const Gap(12),
|
||||
ListTile(
|
||||
leading: const Icon(Symbols.event_available),
|
||||
title: Text('postPublishedAt').tr(),
|
||||
subtitle: Text(
|
||||
controller.publishedAt != null
|
||||
? dateFormatter.format(controller.publishedAt!)
|
||||
: 'unset'.tr(),
|
||||
),
|
||||
trailing: controller.publishedAt != null
|
||||
? IconButton(
|
||||
icon: const Icon(Symbols.cancel),
|
||||
onPressed: () {
|
||||
controller.setPublishedAt(null);
|
||||
},
|
||||
)
|
||||
: null,
|
||||
contentPadding: const EdgeInsets.only(left: 24, right: 18),
|
||||
onTap: () {
|
||||
_selectDate(
|
||||
context,
|
||||
initialDateTime: controller.publishedAt,
|
||||
).then((value) {
|
||||
controller.setPublishedAt(value);
|
||||
});
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Symbols.event_busy),
|
||||
title: Text('postPublishedUntil').tr(),
|
||||
subtitle: Text(
|
||||
controller.publishedUntil != null
|
||||
? dateFormatter.format(controller.publishedUntil!)
|
||||
: 'unset'.tr(),
|
||||
),
|
||||
trailing: controller.publishedUntil != null
|
||||
? IconButton(
|
||||
icon: const Icon(Symbols.cancel),
|
||||
onPressed: () {
|
||||
controller.setPublishedUntil(null);
|
||||
},
|
||||
)
|
||||
: null,
|
||||
contentPadding: const EdgeInsets.only(left: 24, right: 18),
|
||||
onTap: () {
|
||||
_selectDate(
|
||||
context,
|
||||
initialDateTime: controller.publishedUntil,
|
||||
).then((value) {
|
||||
controller.setPublishedUntil(value);
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
).padding(horizontal: 24, vertical: 8);
|
||||
).padding(vertical: 8);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
10
lib/widgets/post/post_mini_editor.dart
Normal file
10
lib/widgets/post/post_mini_editor.dart
Normal file
@ -0,0 +1,10 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class PostMiniEditor extends StatelessWidget {
|
||||
const PostMiniEditor({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Placeholder();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user