fix: android file permission issue (#6244)

* fix: invalid value when inserting image

* fix: upgrade share_plus version and use temp dir as android export log path

* fix: only noto emoji on Linux

* chore: upgrade android minSdkVersion to 29
This commit is contained in:
Lucas.Xu 2024-09-09 17:09:54 +08:00 committed by GitHub
parent 7a0c6a829b
commit 38d69c0b58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 108 additions and 67 deletions

View File

@ -52,7 +52,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "io.appflowy.appflowy" applicationId "io.appflowy.appflowy"
minSdkVersion 24 minSdkVersion 29
targetSdkVersion 34 targetSdkVersion 34
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName

View File

@ -28,7 +28,6 @@ class HomePageSettingsPopupMenu extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return PopupMenuButton<_MobileSettingsPopupMenuItem>( return PopupMenuButton<_MobileSettingsPopupMenuItem>(
offset: const Offset(0, 36), offset: const Offset(0, 36),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/mobile/application/mobile_router.dart';
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
@ -297,7 +299,7 @@ class _SingleMobileInnerViewItemState extends State<SingleMobileInnerViewItem> {
final icon = widget.view.icon.value.isNotEmpty final icon = widget.view.icon.value.isNotEmpty
? FlowyText.emoji( ? FlowyText.emoji(
widget.view.icon.value, widget.view.icon.value,
fontSize: 18.0, fontSize: Platform.isAndroid ? 16.0 : 18.0,
figmaLineHeight: 20.0, figmaLineHeight: 20.0,
optimizeEmojiAlign: true, optimizeEmojiAlign: true,
) )

View File

@ -36,7 +36,7 @@ class EmojiText extends StatelessWidget {
} }
void _loadFallbackFontFamily() { void _loadFallbackFontFamily() {
if (Platform.isLinux || Platform.isAndroid) { if (Platform.isLinux) {
final notoColorEmoji = GoogleFonts.notoColorEmoji().fontFamily; final notoColorEmoji = GoogleFonts.notoColorEmoji().fontFamily;
if (notoColorEmoji != null) { if (notoColorEmoji != null) {
_cachedFallbackFontFamily = [notoColorEmoji]; _cachedFallbackFontFamily = [notoColorEmoji];

View File

@ -1,7 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
@ -24,6 +22,7 @@ import 'package:flowy_infra/uuid.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/snap_bar.dart'; import 'package:flowy_infra_ui/style_widget/snap_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
@ -259,6 +258,10 @@ class ImagePlaceholderState extends State<ImagePlaceholder> {
bool hasError = false; bool hasError = false;
if (_isLocalMode()) { if (_isLocalMode()) {
if (urls.isEmpty) {
return;
}
final first = urls.removeAt(0); final first = urls.removeAt(0);
final firstPath = await saveImageToLocalStorage(first); final firstPath = await saveImageToLocalStorage(first);
final transaction = editorState.transaction; final transaction = editorState.transaction;

View File

@ -637,11 +637,11 @@ class _PopupMenuState<T> extends State<_PopupMenu<T>> {
); );
} }
final CurveTween opacity = final _CurveTween opacity =
CurveTween(curve: const Interval(0.0, 1.0 / 3.0)); _CurveTween(curve: const Interval(0.0, 1.0 / 3.0));
final CurveTween width = CurveTween(curve: Interval(0.0, unit)); final _CurveTween width = _CurveTween(curve: Interval(0.0, unit));
final CurveTween height = final _CurveTween height =
CurveTween(curve: Interval(0.0, unit * widget.route.items.length)); _CurveTween(curve: Interval(0.0, unit * widget.route.items.length));
final Widget child = ConstrainedBox( final Widget child = ConstrainedBox(
constraints: widget.constraints ?? constraints: widget.constraints ??
@ -1644,3 +1644,20 @@ extension PopupMenuColors on BuildContext {
return const Color(0xFF23262B); return const Color(0xFF23262B);
} }
} }
class _CurveTween extends Animatable<double> {
/// Creates a curve tween.
_CurveTween({required this.curve});
/// The curve to use when transforming the value of the animation.
Curve curve;
@override
double transform(double t) {
return curve.transform(t.clamp(0, 1));
}
@override
String toString() =>
'${objectRuntimeType(this, 'CurveTween')}(curve: $curve)';
}

View File

@ -1,13 +1,14 @@
import 'dart:io'; import 'dart:io';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/presentation/home/toast.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:archive/archive_io.dart'; import 'package:archive/archive_io.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart'; import 'package:share_plus/share_plus.dart';
import 'package:toastification/toastification.dart';
Future<void> shareLogFiles(BuildContext? context) async { Future<void> shareLogFiles(BuildContext? context) async {
final dir = await getApplicationSupportDirectory(); final dir = await getApplicationSupportDirectory();
@ -23,9 +24,10 @@ Future<void> shareLogFiles(BuildContext? context) async {
if (archiveLogFiles.isEmpty) { if (archiveLogFiles.isEmpty) {
if (context != null && context.mounted) { if (context != null && context.mounted) {
showSnackBarMessage( showToastNotification(
context, context,
LocaleKeys.noLogFiles.tr(), message: LocaleKeys.noLogFiles.tr(),
type: ToastificationType.error,
); );
} }
return; return;
@ -38,20 +40,38 @@ Future<void> shareLogFiles(BuildContext? context) async {
final zip = zipEncoder.encode(archive); final zip = zipEncoder.encode(archive);
if (zip == null) { if (zip == null) {
if (context != null && context.mounted) {
showToastNotification(
context,
message: LocaleKeys.noLogFiles.tr(),
type: ToastificationType.error,
);
}
return; return;
} }
// create a zipped appflowy logs file // create a zipped appflowy logs file
final path = Platform.isAndroid ? '/storage/emulated/0/Download' : dir.path; try {
final zipFile = final tempDirectory = await getTemporaryDirectory();
await File(p.join(path, 'appflowy_logs.zip')).writeAsBytes(zip); final path = Platform.isAndroid ? tempDirectory.path : dir.path;
final zipFile =
await File(p.join(path, 'appflowy_logs.zip')).writeAsBytes(zip);
if (Platform.isIOS) { if (Platform.isIOS) {
await Share.shareUri(zipFile.uri); await Share.shareUri(zipFile.uri);
} else { } else {
await Share.shareXFiles([XFile(zipFile.path)]); await Share.shareXFiles([XFile(zipFile.path)]);
}
// delete the zipped appflowy logs file
await zipFile.delete();
} catch (e) {
if (context != null && context.mounted) {
showToastNotification(
context,
message: e.toString(),
type: ToastificationType.error,
);
}
} }
// delete the zipped appflowy logs file
await zipFile.delete();
} }

View File

@ -240,5 +240,5 @@ class FlowyText extends StatelessWidget {
return null; return null;
} }
bool get _useNotoColorEmoji => Platform.isLinux || Platform.isAndroid; bool get _useNotoColorEmoji => Platform.isLinux;
} }

View File

@ -382,10 +382,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: cross_file name: cross_file
sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.4+1" version: "0.3.4+2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -430,18 +430,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: device_info_plus name: device_info_plus
sha256: eead12d1a1ed83d8283ab4c2f3fca23ac4082f29f25f29dff0f758f57d06ec91 sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.1.0" version: "10.1.2"
device_info_plus_platform_interface: device_info_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: device_info_plus_platform_interface name: device_info_plus_platform_interface
sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64 sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.0.0" version: "7.0.1"
diff_match_patch: diff_match_patch:
dependency: transitive dependency: transitive
description: description:
@ -566,10 +566,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: file_picker name: file_picker
sha256: "29c90806ac5f5fb896547720b73b17ee9aed9bba540dc5d91fe29f8c5745b10a" sha256: "167bb619cdddaa10ef2907609feb8a79c16dfa479d3afaf960f8e223f754bf12"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.0.3" version: "8.1.2"
file_selector_linux: file_selector_linux:
dependency: transitive dependency: transitive
description: description:
@ -829,10 +829,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: fluttertoast name: fluttertoast
sha256: "7eae679e596a44fdf761853a706f74979f8dd3cd92cf4e23cae161fda091b847" sha256: "95f349437aeebe524ef7d6c9bde3e6b4772717cf46a0eb6a3ceaddc740b297cc"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.2.6" version: "8.2.8"
freezed: freezed:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -970,10 +970,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: http name: http
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.2"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
@ -1367,18 +1367,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: package_info_plus name: package_info_plus
sha256: cb44f49b6e690fa766f023d5b22cac6b9affe741dd792b6ac7ad4fabe0d7b097 sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.0" version: "8.0.2"
package_info_plus_platform_interface: package_info_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: package_info_plus_platform_interface name: package_info_plus_platform_interface
sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "3.0.1"
path: path:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1551,10 +1551,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: platform name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.4" version: "3.1.5"
plugin_platform_interface: plugin_platform_interface:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -1743,18 +1743,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: share_plus name: share_plus
sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900" sha256: "468c43f285207c84bcabf5737f33b914ceb8eb38398b91e5e3ad1698d1b72a52"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.2.2" version: "10.0.2"
share_plus_platform_interface: share_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: share_plus_platform_interface name: share_plus_platform_interface
sha256: df08bc3a07d01f5ea47b45d03ffcba1fa9cd5370fb44b3f38c70e42cced0f956 sha256: "6ababf341050edff57da8b6990f11f4e99eaba837865e2e6defe16d039619db5"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.1" version: "5.0.0"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1799,10 +1799,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_web name: shared_preferences_web
sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.0" version: "2.2.1"
shared_preferences_windows: shared_preferences_windows:
dependency: transitive dependency: transitive
description: description:
@ -1989,10 +1989,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.3.0"
string_validator: string_validator:
dependency: "direct main" dependency: "direct main"
description: description:
@ -2038,10 +2038,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: super_native_extensions name: super_native_extensions
sha256: b03f19e54744b65940a7c2cb4f93abd4819b5355aa3464d7b3c9a013b6b76db1 sha256: "9d674b8c71e16f586b3967e67a6faa83c35e3d9ea4f64bca8551badfddf992cb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.18" version: "0.8.20"
sync_http: sync_http:
dependency: transitive dependency: transitive
description: description:
@ -2230,18 +2230,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a" sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.1" version: "2.3.3"
url_launcher_windows: url_launcher_windows:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_windows name: url_launcher_windows
sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.1" version: "3.1.2"
url_protocol: url_protocol:
dependency: "direct main" dependency: "direct main"
description: description:
@ -2311,10 +2311,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.1" version: "14.2.5"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
@ -2327,18 +2327,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: web name: web
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "1.0.0"
web_socket_channel: web_socket_channel:
dependency: transitive dependency: transitive
description: description:
name: web_socket_channel name: web_socket_channel
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.5" version: "2.4.0"
webdriver: webdriver:
dependency: transitive dependency: transitive
description: description:
@ -2359,10 +2359,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.2.0" version: "5.5.4"
win32_registry: win32_registry:
dependency: transitive dependency: transitive
description: description:

View File

@ -65,7 +65,7 @@ dependencies:
expandable: ^5.0.1 expandable: ^5.0.1
flex_color_picker: ^3.5.1 flex_color_picker: ^3.5.1
highlight: ^0.7.0 highlight: ^0.7.0
package_info_plus: ^6.0.0 package_info_plus: ^8.0.2
url_launcher: ^6.1.11 url_launcher: ^6.1.11
connectivity_plus: ^5.0.2 connectivity_plus: ^5.0.2
easy_localization: ^3.0.2 easy_localization: ^3.0.2
@ -119,7 +119,7 @@ dependencies:
keyboard_height_plugin: ^0.1.5 keyboard_height_plugin: ^0.1.5
scrollable_positioned_list: ^0.3.8 scrollable_positioned_list: ^0.3.8
flutter_cache_manager: ^3.3.1 flutter_cache_manager: ^3.3.1
share_plus: ^7.2.1 share_plus: ^10.0.2
sheet: sheet:
file: ^7.0.0 file: ^7.0.0
avatar_stack: ^1.2.0 avatar_stack: ^1.2.0