Add attachment from camera

This commit is contained in:
LittleSheep 2024-12-08 11:37:03 +08:00
parent be9b3f76d2
commit a693bfdc94
5 changed files with 92 additions and 11 deletions

View File

@ -256,6 +256,8 @@
},
"addAttachmentFromAlbum": "Add from album",
"addAttachmentFromClipboard": "Paste file",
"addAttachmentFromCameraPhoto": "Take photo",
"addAttachmentFromCameraVideo": "Take video",
"attachmentPastedImage": "Pasted Image",
"attachmentInsertLink": "Insert Link",
"attachmentSetAsPostThumbnail": "Set as post thumbnail",

View File

@ -256,6 +256,8 @@
},
"addAttachmentFromAlbum": "从相册中添加附件",
"addAttachmentFromClipboard": "粘贴附件",
"addAttachmentFromCameraPhoto": "拍摄照片",
"addAttachmentFromCameraVideo": "拍摄视频",
"attachmentPastedImage": "粘贴的图片",
"attachmentInsertLink": "插入连接",
"attachmentSetAsPostThumbnail": "设置为帖子缩略图",

View File

@ -1,6 +1,9 @@
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
@ -75,6 +78,16 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
final _imagePicker = ImagePicker();
void _takeMedia(bool isVideo) async {
final result = isVideo
? await _imagePicker.pickVideo(source: ImageSource.camera)
: await _imagePicker.pickImage(source: ImageSource.camera);
if (result == null) return;
_writeController.addAttachments([
PostWriteMedia.fromFile(result),
]);
}
void _selectMedia() async {
final result = await _imagePicker.pickMultipleMedia();
if (result.isEmpty) return;
@ -396,6 +409,32 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
color: Theme.of(context).colorScheme.primary,
),
itemBuilder: (context) => [
if (!kIsWeb && !Platform.isLinux && !Platform.isMacOS && !Platform.isWindows)
PopupMenuItem(
child: Row(
children: [
const Icon(Symbols.photo_camera),
const Gap(16),
Text('addAttachmentFromCameraPhoto').tr(),
],
),
onTap: () {
_takeMedia(false);
},
),
if (!kIsWeb && !Platform.isLinux && !Platform.isMacOS && !Platform.isWindows)
PopupMenuItem(
child: Row(
children: [
const Icon(Symbols.videocam),
const Gap(16),
Text('addAttachmentFromCameraVideo').tr(),
],
),
onTap: () {
_takeMedia(true);
},
),
PopupMenuItem(
child: Row(
children: [
@ -443,7 +482,7 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
).padding(horizontal: 16),
],
).padding(
bottom: MediaQuery.of(context).padding.bottom,
bottom: MediaQuery.of(context).padding.bottom + 8,
top: 4,
),
),

View File

@ -1,4 +1,7 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:image_picker/image_picker.dart';
@ -125,6 +128,17 @@ class ChatMessageInputState extends State<ChatMessageInput> {
final List<PostWriteMedia> _attachments = List.empty(growable: true);
final _imagePicker = ImagePicker();
void _takeMedia(bool isVideo) async {
final result = isVideo
? await _imagePicker.pickVideo(source: ImageSource.camera)
: await _imagePicker.pickImage(source: ImageSource.camera);
if (result == null) return;
_attachments.add(
PostWriteMedia.fromFile(result),
);
setState(() {});
}
void _selectMedia() async {
final result = await _imagePicker.pickMultipleMedia();
if (result.isEmpty) return;
@ -283,6 +297,32 @@ class ChatMessageInputState extends State<ChatMessageInput> {
color: Theme.of(context).colorScheme.primary,
),
itemBuilder: (context) => [
if (!kIsWeb && !Platform.isLinux && !Platform.isMacOS && !Platform.isWindows)
PopupMenuItem(
child: Row(
children: [
const Icon(Symbols.photo_camera),
const Gap(16),
Text('addAttachmentFromCameraPhoto').tr(),
],
),
onTap: () {
_takeMedia(false);
},
),
if (!kIsWeb && !Platform.isLinux && !Platform.isMacOS && !Platform.isWindows)
PopupMenuItem(
child: Row(
children: [
const Icon(Symbols.videocam),
const Gap(16),
Text('addAttachmentFromCameraVideo').tr(),
],
),
onTap: () {
_takeMedia(true);
},
),
PopupMenuItem(
child: Row(
children: [

View File

@ -8,6 +8,7 @@ import 'package:surface/providers/navigation.dart';
class AppNavigationDrawer extends StatefulWidget {
final double? elevation;
const AppNavigationDrawer({super.key, this.elevation});
@override
@ -19,9 +20,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
context
.read<NavigationProvider>()
.autoDetectIndex(GoRouter.maybeOf(context));
context.read<NavigationProvider>().autoDetectIndex(GoRouter.maybeOf(context));
});
}
@ -29,9 +28,7 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
Widget build(BuildContext context) {
final nav = context.watch<NavigationProvider>();
final backgroundColor = ResponsiveBreakpoints.of(context).largerThan(TABLET)
? Colors.transparent
: null;
final backgroundColor = ResponsiveBreakpoints.of(context).largerThan(TABLET) ? Colors.transparent : null;
return ListenableBuilder(
listenable: nav,
@ -51,13 +48,14 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Solar Network').bold(),
Text('Canary Preview 2.0α').fontSize(12).textColor(
Theme.of(context).colorScheme.onSurface.withOpacity(0.5)),
Text('Canary Preview 2.0α')
.fontSize(12)
.textColor(Theme.of(context).colorScheme.onSurface.withOpacity(0.5)),
],
).padding(
horizontal: 32,
top: MediaQuery.of(context).padding.top > 32 ? 8 : 32,
bottom: 8,
top: MediaQuery.of(context).padding.top + 8,
bottom: 12,
),
...destinations.where((ele) => ele.isPinned).map((ele) {
return NavigationDrawerDestination(