chore: 添加 iOS/Android 相机和相册权限配置

This commit is contained in:
qzl
2026-03-11 17:32:00 +08:00
parent e2eff03060
commit 177ed616bf
5 changed files with 59 additions and 28 deletions
@@ -1,6 +1,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<application <application
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
+4
View File
@@ -45,5 +45,9 @@
<true/> <true/>
<key>UIApplicationSupportsIndirectInputEvents</key> <key>UIApplicationSupportsIndirectInputEvents</key>
<true/> <true/>
<key>NSCameraUsageDescription</key>
<string>需要使用相机来拍摄照片</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册来选择照片</string>
</dict> </dict>
</plist> </plist>
@@ -44,7 +44,6 @@ class _CalendarDayWeekScreenState extends State<CalendarDayWeekScreen>
final ScrollController _dayStripController = ScrollController(); final ScrollController _dayStripController = ScrollController();
Key _eventsKey = UniqueKey(); Key _eventsKey = UniqueKey();
List<ScheduleItemModel> _events = const []; List<ScheduleItemModel> _events = const [];
String? _lastRoute;
@override @override
void initState() { void initState() {
@@ -62,21 +61,18 @@ class _CalendarDayWeekScreenState extends State<CalendarDayWeekScreen>
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollToSelectedDate(); _scrollToSelectedDate();
_lastRoute = GoRouterState.of(context).uri.toString(); _setupRouteListener();
}); });
} }
@override void _setupRouteListener() {
void didChangeDependencies() { final router = GoRouter.of(context);
super.didChangeDependencies(); router.routerDelegate.addListener(_onRouteChange);
final currentRoute = GoRouterState.of(context).uri.toString(); }
if (_lastRoute != null && _lastRoute != currentRoute) {
if (!currentRoute.contains('/events/')) { void _onRouteChange() {
_loadEvents(); _loadEvents();
} }
}
_lastRoute = currentRoute;
}
void _updateMonthDates() { void _updateMonthDates() {
_monthDates = monthDatesFor(_selectedDate); _monthDates = monthDatesFor(_selectedDate);
@@ -94,6 +90,9 @@ class _CalendarDayWeekScreenState extends State<CalendarDayWeekScreen>
@override @override
void dispose() { void dispose() {
try {
GoRouter.of(context).routerDelegate.removeListener(_onRouteChange);
} catch (_) {}
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
_dayStripController.dispose(); _dayStripController.dispose();
super.dispose(); super.dispose();
@@ -27,7 +27,6 @@ class _CalendarMonthScreenState extends State<CalendarMonthScreen>
late DateTime _selectedDate; late DateTime _selectedDate;
Key _eventsKey = UniqueKey(); Key _eventsKey = UniqueKey();
final Map<String, List<ScheduleItemModel>> _eventsByDay = {}; final Map<String, List<ScheduleItemModel>> _eventsByDay = {};
String? _lastRoute;
@override @override
void initState() { void initState() {
@@ -45,21 +44,18 @@ class _CalendarMonthScreenState extends State<CalendarMonthScreen>
_loadMonthEvents(); _loadMonthEvents();
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_lastRoute = GoRouterState.of(context).uri.toString(); _setupRouteListener();
}); });
} }
@override void _setupRouteListener() {
void didChangeDependencies() { final router = GoRouter.of(context);
super.didChangeDependencies(); router.routerDelegate.addListener(_onRouteChange);
final currentRoute = GoRouterState.of(context).uri.toString(); }
if (_lastRoute != null && _lastRoute != currentRoute) {
if (!currentRoute.contains('/events/')) { void _onRouteChange() {
_loadMonthEvents(); _loadMonthEvents();
} }
}
_lastRoute = currentRoute;
}
Future<void> _loadMonthEvents() async { Future<void> _loadMonthEvents() async {
final start = DateTime(_currentMonth.year, _currentMonth.month, 1); final start = DateTime(_currentMonth.year, _currentMonth.month, 1);
@@ -85,6 +81,9 @@ class _CalendarMonthScreenState extends State<CalendarMonthScreen>
@override @override
void dispose() { void dispose() {
try {
GoRouter.of(context).routerDelegate.removeListener(_onRouteChange);
} catch (_) {}
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
super.dispose(); super.dispose();
} }
@@ -113,8 +113,13 @@ class _CreateEventSheetState extends State<CreateEventSheet>
} }
DateTime _roundToNearestMinute(DateTime dt, int interval) { DateTime _roundToNearestMinute(DateTime dt, int interval) {
final minute = (dt.minute / interval).round() * interval; final totalMinutes = dt.hour * 60 + dt.minute;
return DateTime(dt.year, dt.month, dt.day, dt.hour, minute % 60); final rounded = ((totalMinutes / interval).round() * interval);
final hours = rounded ~/ 60;
final minutes = rounded % 60;
final dayOffset = hours >= 24 ? 1 : 0;
final newHour = hours % 24;
return DateTime(dt.year, dt.month, dt.day + dayOffset, newHour, minutes);
} }
@override @override
@@ -242,8 +247,27 @@ class _CreateEventSheetState extends State<CreateEventSheet>
_endTime ?? _startTime, _endTime ?? _startTime,
(date, time) { (date, time) {
setState(() { setState(() {
final startDateTime = DateTime(
_startDate.year,
_startDate.month,
_startDate.day,
_startTime.hour,
_startTime.minute,
);
final endDateTime = DateTime(
date.year,
date.month,
date.day,
time.hour,
time.minute,
);
if (endDateTime.isBefore(startDateTime)) {
_endDate = _startDate;
_endTime = _startTime;
} else {
_endDate = date; _endDate = date;
_endTime = time; _endTime = time;
}
}); });
}, },
isOptional: true, isOptional: true,