✨ App updates & web deeplink
This commit is contained in:
parent
392aebcad7
commit
39fb4d474f
@ -33,22 +33,6 @@
|
||||
</intent-filter>
|
||||
|
||||
<!-- Sharing Intents -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="sn.solsynth.dev"
|
||||
android:pathPrefix="/invite"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data
|
||||
android:mimeType="*/*"
|
||||
android:scheme="content" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
@ -370,6 +370,8 @@
|
||||
"dailyCheckNegativeHint6": "Going out",
|
||||
"dailyCheckNegativeHint6Description": "Forgot your umbrella and got caught in the rain",
|
||||
"happyBirthday": "Happy birthday, {}!",
|
||||
"celebrateMerryXmas": "Merry christmas, {}!",
|
||||
"celebrateNewYear": "Happy new year, {}!",
|
||||
"friendNew": "Add Friend",
|
||||
"friendRequests": "Friend Requests",
|
||||
"friendRequestsDescription": {
|
||||
@ -455,5 +457,7 @@
|
||||
"poweredBy": "Powered by {}",
|
||||
"shareIntent": "Share",
|
||||
"shareIntentDescription": "What do you want to do with the content you are sharing?",
|
||||
"shareIntentPostStory": "Post a Story"
|
||||
"shareIntentPostStory": "Post a Story",
|
||||
"updateAvailable": "Update Available",
|
||||
"updateOngoing": "正在更新,请稍后..."
|
||||
}
|
||||
|
@ -368,6 +368,8 @@
|
||||
"dailyCheckNegativeHint6": "出门",
|
||||
"dailyCheckNegativeHint6Description": "忘带伞遇上大雨",
|
||||
"happyBirthday": "生日快乐,{}!",
|
||||
"celebrateMerryXmas": "圣诞快乐,{}!",
|
||||
"celebrateNewYear": "新年快乐,{}!",
|
||||
"friendNew": "添加好友",
|
||||
"friendRequests": "好友请求",
|
||||
"friendRequestsDescription": {
|
||||
@ -453,5 +455,7 @@
|
||||
"poweredBy": "由 {} 提供支持",
|
||||
"shareIntent": "分享",
|
||||
"shareIntentDescription": "您想对您分享的内容做些什么?",
|
||||
"shareIntentPostStory": "发布动态"
|
||||
"shareIntentPostStory": "发布动态",
|
||||
"updateAvailable": "检测到更新可用",
|
||||
"updateOngoing": "正在更新,请稍后……"
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
||||
import 'package:croppy/croppy.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:easy_localization_loader/easy_localization_loader.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
@ -12,9 +13,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:relative_time/relative_time.dart';
|
||||
import 'package:responsive_framework/responsive_framework.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:surface/firebase_options.dart';
|
||||
import 'package:surface/providers/channel.dart';
|
||||
@ -38,7 +41,9 @@ import 'package:surface/types/realm.dart';
|
||||
import 'package:flutter_web_plugins/url_strategy.dart' show usePathUrlStrategy;
|
||||
import 'package:surface/widgets/dialog.dart';
|
||||
import 'package:surface/widgets/version_label.dart';
|
||||
import 'package:version/version.dart';
|
||||
import 'package:workmanager/workmanager.dart';
|
||||
import 'package:in_app_review/in_app_review.dart';
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void appBackgroundDispatcher() {
|
||||
@ -125,7 +130,7 @@ class SolianApp extends StatelessWidget {
|
||||
Provider(create: (ctx) => HomeWidgetProvider(ctx)),
|
||||
|
||||
// Preferences layer
|
||||
Provider(create: (ctx) => ConfigProvider(ctx)),
|
||||
ChangeNotifierProvider(create: (ctx) => ConfigProvider(ctx)),
|
||||
|
||||
// Display layer
|
||||
ChangeNotifierProvider(create: (_) => ThemeProvider()),
|
||||
@ -201,6 +206,56 @@ class _AppSplashScreen extends StatefulWidget {
|
||||
class _AppSplashScreenState extends State<_AppSplashScreen> {
|
||||
bool _isReady = false;
|
||||
|
||||
void _tryRequestRating() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
if (prefs.containsKey('first_boot_time')) {
|
||||
final rawTime = prefs.getString('first_boot_time');
|
||||
final time = DateTime.tryParse(rawTime ?? '');
|
||||
if (time != null && time.isBefore(DateTime.now().subtract(const Duration(days: 3)))) {
|
||||
final inAppReview = InAppReview.instance;
|
||||
if (prefs.getBool('rating_requested') == true) return;
|
||||
if (await inAppReview.isAvailable()) {
|
||||
await inAppReview.requestReview();
|
||||
prefs.setBool('rating_requested', true);
|
||||
} else {
|
||||
log('Unable request app review, unavailable');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
prefs.setString('first_boot_time', DateTime.now().toIso8601String());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _checkForUpdate() async {
|
||||
if (kIsWeb) return;
|
||||
try {
|
||||
final info = await PackageInfo.fromPlatform();
|
||||
final localVersionString = '${info.version}+${info.buildNumber}';
|
||||
final resp = await Dio(
|
||||
BaseOptions(
|
||||
sendTimeout: const Duration(seconds: 60),
|
||||
receiveTimeout: const Duration(seconds: 60),
|
||||
),
|
||||
).get(
|
||||
'https://git.solsynth.dev/api/v1/repos/HyperNet/Surface/tags?page=1&limit=1',
|
||||
);
|
||||
final remoteVersionString = (resp.data as List).firstOrNull?['name'] ?? '0.0.0+0';
|
||||
final remoteVersion = Version.parse(remoteVersionString.split('+').first);
|
||||
final localVersion = Version.parse(localVersionString.split('+').first);
|
||||
final remoteBuildNumber = int.tryParse(remoteVersionString.split('+').last) ?? 0;
|
||||
final localBuildNumber = int.tryParse(localVersionString.split('+').last) ?? 0;
|
||||
log("[Update] Local: $localVersionString, Remote: $remoteVersionString");
|
||||
// TODO remove this true
|
||||
if ((remoteVersion > localVersion || remoteBuildNumber > localBuildNumber) && mounted) {
|
||||
final config = context.read<ConfigProvider>();
|
||||
config.setUpdate(remoteVersionString);
|
||||
log("[Update] Update available: $remoteVersionString");
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) context.showErrorDialog('Unable to check update: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _initialize() async {
|
||||
try {
|
||||
final home = context.read<HomeWidgetProvider>();
|
||||
@ -235,7 +290,11 @@ class _AppSplashScreenState extends State<_AppSplashScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initialize().then((_) => _postInitialization());
|
||||
_initialize().then((_) {
|
||||
_postInitialization();
|
||||
_tryRequestRating();
|
||||
_checkForUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -16,7 +16,7 @@ const Map<String, FilterQuality> kImageQualityLevel = {
|
||||
'settingsImageQualityHigh': FilterQuality.high,
|
||||
};
|
||||
|
||||
class ConfigProvider {
|
||||
class ConfigProvider extends ChangeNotifier {
|
||||
late final SharedPreferences prefs;
|
||||
|
||||
late final HomeWidgetProvider _home;
|
||||
@ -36,8 +36,16 @@ class ConfigProvider {
|
||||
String get serverUrl {
|
||||
return prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
|
||||
}
|
||||
|
||||
set serverUrl(String url) {
|
||||
prefs.setString(kNetworkServerStoreKey, url);
|
||||
_home.saveWidgetData("nex_server_url", url);
|
||||
}
|
||||
|
||||
String? updatableVersion;
|
||||
|
||||
void setUpdate(String newVersion) {
|
||||
updatableVersion = newVersion;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
import 'dart:io';
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_app_update/flutter_app_update.dart';
|
||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
@ -10,6 +13,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:surface/providers/config.dart';
|
||||
import 'package:surface/providers/post.dart';
|
||||
import 'package:surface/providers/sn_network.dart';
|
||||
import 'package:surface/providers/userinfo.dart';
|
||||
@ -69,18 +73,15 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
body: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return Align(
|
||||
alignment: constraints.maxWidth > 640
|
||||
? Alignment.center
|
||||
: Alignment.topCenter,
|
||||
alignment: constraints.maxWidth > 640 ? Alignment.center : Alignment.topCenter,
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(maxWidth: 640),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: constraints.maxWidth > 640
|
||||
? MainAxisAlignment.center
|
||||
: MainAxisAlignment.start,
|
||||
mainAxisAlignment: constraints.maxWidth > 640 ? MainAxisAlignment.center : MainAxisAlignment.start,
|
||||
children: [
|
||||
_HomeDashSpecialDayWidget().padding(top: 8, horizontal: 8),
|
||||
_HomeDashSpecialDayWidget().padding(bottom: 8, horizontal: 8),
|
||||
_HomeDashUpdateWidget(padding: const EdgeInsets.only(bottom: 8, left: 8, right: 8)),
|
||||
StaggeredGrid.extent(
|
||||
maxCrossAxisExtent: 280,
|
||||
mainAxisSpacing: 8,
|
||||
@ -104,6 +105,52 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
class _HomeDashUpdateWidget extends StatelessWidget {
|
||||
final EdgeInsets? padding;
|
||||
|
||||
const _HomeDashUpdateWidget({super.key, this.padding});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final config = context.watch<ConfigProvider>();
|
||||
|
||||
return ListenableBuilder(
|
||||
listenable: config,
|
||||
builder: (context, _) {
|
||||
if (config.updatableVersion != null) {
|
||||
return Container(
|
||||
padding: padding,
|
||||
child: Card(
|
||||
child: ListTile(
|
||||
leading: Icon(Symbols.update),
|
||||
title: Text('updateAvailable').tr(),
|
||||
subtitle: Text(config.updatableVersion!),
|
||||
trailing: (kIsWeb || Platform.isWindows || Platform.isLinux)
|
||||
? null
|
||||
: IconButton(
|
||||
icon: const Icon(Symbols.arrow_right_alt),
|
||||
onPressed: () {
|
||||
final model = UpdateModel(
|
||||
'https://files.solsynth.dev/d/production01/solian/app-arm64-v8a-release.apk',
|
||||
'solian-app-release-${config.updatableVersion!}.apk',
|
||||
'ic_notification',
|
||||
'https://apps.apple.com/us/app/solian/id6499032345',
|
||||
);
|
||||
AzhonAppUpdate.update(model);
|
||||
context.showSnackbar('updateOngoing'.tr());
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return SizedBox.shrink();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _HomeDashSpecialDayWidget extends StatelessWidget {
|
||||
const _HomeDashSpecialDayWidget({super.key});
|
||||
|
||||
@ -112,10 +159,10 @@ class _HomeDashSpecialDayWidget extends StatelessWidget {
|
||||
final ua = context.watch<UserProvider>();
|
||||
final today = DateTime.now();
|
||||
final birthday = ua.user?.profile?.birthday?.toLocal();
|
||||
final isBirthday = birthday != null &&
|
||||
birthday.day == today.day &&
|
||||
birthday.month == today.month;
|
||||
final isBirthday = birthday != null && birthday.day == today.day && birthday.month == today.month;
|
||||
|
||||
return Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
if (isBirthday)
|
||||
Card(
|
||||
@ -124,6 +171,20 @@ class _HomeDashSpecialDayWidget extends StatelessWidget {
|
||||
title: Text('happyBirthday').tr(args: [ua.user?.nick ?? 'user']),
|
||||
),
|
||||
).padding(bottom: 8),
|
||||
if (today.month == 12 && today.day == 25)
|
||||
Card(
|
||||
child: ListTile(
|
||||
leading: Text('🎄').fontSize(24),
|
||||
title: Text('celebrateMerryXmas').tr(args: [ua.user?.nick ?? 'user']),
|
||||
),
|
||||
),
|
||||
if (today.month == 1 && today.day == 1)
|
||||
Card(
|
||||
child: ListTile(
|
||||
leading: Text('🎉').fontSize(24),
|
||||
title: Text('celebrateNewYear').tr(args: [ua.user?.nick ?? 'user']),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -174,20 +235,15 @@ class _HomeDashCheckInWidgetState extends State<_HomeDashCheckInWidget> {
|
||||
}
|
||||
|
||||
Widget _buildDetailChunk(int index, bool positive) {
|
||||
final prefix =
|
||||
positive ? 'dailyCheckPositiveHint' : 'dailyCheckNegativeHint';
|
||||
final mod =
|
||||
positive ? kSuggestionPositiveHintCount : kSuggestionNegativeHintCount;
|
||||
final prefix = positive ? 'dailyCheckPositiveHint' : 'dailyCheckNegativeHint';
|
||||
final mod = positive ? kSuggestionPositiveHintCount : kSuggestionNegativeHintCount;
|
||||
final pos = math.max(1, _todayRecord!.resultModifiers[index] % mod);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
prefix.tr(args: ['$prefix$pos'.tr()]),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(fontWeight: FontWeight.bold),
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
'$prefix${pos}Description',
|
||||
@ -222,10 +278,7 @@ class _HomeDashCheckInWidgetState extends State<_HomeDashCheckInWidget> {
|
||||
else
|
||||
Text(
|
||||
'dailyCheckEverythingIsNegative',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(fontWeight: FontWeight.bold),
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.bold),
|
||||
).tr(),
|
||||
const Gap(8),
|
||||
if (_todayRecord?.resultTier != 4)
|
||||
@ -241,10 +294,7 @@ class _HomeDashCheckInWidgetState extends State<_HomeDashCheckInWidget> {
|
||||
else
|
||||
Text(
|
||||
'dailyCheckEverythingIsPositive',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(fontWeight: FontWeight.bold),
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.bold),
|
||||
).tr(),
|
||||
],
|
||||
),
|
||||
@ -362,12 +412,10 @@ class _HomeDashNotificationWidget extends StatefulWidget {
|
||||
const _HomeDashNotificationWidget({super.key});
|
||||
|
||||
@override
|
||||
State<_HomeDashNotificationWidget> createState() =>
|
||||
_HomeDashNotificationWidgetState();
|
||||
State<_HomeDashNotificationWidget> createState() => _HomeDashNotificationWidgetState();
|
||||
}
|
||||
|
||||
class _HomeDashNotificationWidgetState
|
||||
extends State<_HomeDashNotificationWidget> {
|
||||
class _HomeDashNotificationWidgetState extends State<_HomeDashNotificationWidget> {
|
||||
int? _count;
|
||||
|
||||
Future<void> _fetchNotificationCount() async {
|
||||
@ -404,9 +452,7 @@ class _HomeDashNotificationWidgetState
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
).tr(),
|
||||
Text(
|
||||
_count == null
|
||||
? 'loading'.tr()
|
||||
: 'notificationUnreadCount'.plural(_count ?? 0),
|
||||
_count == null ? 'loading'.tr() : 'notificationUnreadCount'.plural(_count ?? 0),
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
],
|
||||
@ -437,12 +483,10 @@ class _HomeDashRecommendationPostWidget extends StatefulWidget {
|
||||
const _HomeDashRecommendationPostWidget({super.key});
|
||||
|
||||
@override
|
||||
State<_HomeDashRecommendationPostWidget> createState() =>
|
||||
_HomeDashRecommendationPostWidgetState();
|
||||
State<_HomeDashRecommendationPostWidget> createState() => _HomeDashRecommendationPostWidgetState();
|
||||
}
|
||||
|
||||
class _HomeDashRecommendationPostWidgetState
|
||||
extends State<_HomeDashRecommendationPostWidget> {
|
||||
class _HomeDashRecommendationPostWidgetState extends State<_HomeDashRecommendationPostWidget> {
|
||||
bool _isBusy = false;
|
||||
List<SnPost>? _posts;
|
||||
|
||||
@ -491,8 +535,7 @@ class _HomeDashRecommendationPostWidgetState
|
||||
).padding(horizontal: 18, top: 12, bottom: 8),
|
||||
Expanded(
|
||||
child: PageView.builder(
|
||||
scrollBehavior:
|
||||
ScrollConfiguration.of(context).copyWith(dragDevices: {
|
||||
scrollBehavior: ScrollConfiguration.of(context).copyWith(dragDevices: {
|
||||
PointerDeviceKind.mouse,
|
||||
PointerDeviceKind.touch,
|
||||
}),
|
||||
@ -505,8 +548,7 @@ class _HomeDashRecommendationPostWidgetState
|
||||
showMenu: false,
|
||||
).padding(bottom: 8),
|
||||
onTap: () {
|
||||
GoRouter.of(context)
|
||||
.pushNamed('postDetail', pathParameters: {
|
||||
GoRouter.of(context).pushNamed('postDetail', pathParameters: {
|
||||
'slug': _posts![index].id.toString(),
|
||||
});
|
||||
},
|
||||
|
@ -16,6 +16,7 @@ import firebase_messaging
|
||||
import flutter_udid
|
||||
import flutter_webrtc
|
||||
import gal
|
||||
import in_app_review
|
||||
import livekit_client
|
||||
import media_kit_libs_macos_video
|
||||
import media_kit_video
|
||||
@ -41,6 +42,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FlutterUdidPlugin.register(with: registry.registrar(forPlugin: "FlutterUdidPlugin"))
|
||||
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
|
||||
GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin"))
|
||||
InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin"))
|
||||
LiveKitPlugin.register(with: registry.registrar(forPlugin: "LiveKitPlugin"))
|
||||
MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin"))
|
||||
MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin"))
|
||||
|
36
pubspec.lock
36
pubspec.lock
@ -627,6 +627,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.2"
|
||||
flutter_app_update:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_app_update
|
||||
sha256: "09290240949c4651581cd6fc535e52d019e189e694d6019c56b5a56c2e69ba65"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
flutter_cache_manager:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -729,10 +737,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_udid
|
||||
sha256: "63384bd96203aaefccfd7137fab642edda18afede12b0e9e1a2c96fe2589fd07"
|
||||
sha256: be464dc5b1fb7ee894f6a32d65c086ca5e177fdcf9375ac08d77495b98150f84
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.0.1"
|
||||
flutter_web_plugins:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -962,6 +970,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.1+1"
|
||||
in_app_review:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: in_app_review
|
||||
sha256: "36a06771b88fb0e79985b15e7f2ac0f1142e903fe72517f3c055d78bc3bc1819"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.10"
|
||||
in_app_review_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: in_app_review_platform_interface
|
||||
sha256: fed2c755f2125caa9ae10495a3c163aa7fab5af3585a9c62ef4a6920c5b45f10
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1975,6 +1999,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: version
|
||||
sha256: "3d4140128e6ea10d83da32fef2fa4003fccbf6852217bb854845802f04191f94"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
very_good_infinite_list:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -108,6 +108,9 @@ dependencies:
|
||||
home_widget: ^0.7.0
|
||||
receive_sharing_intent: ^1.8.1
|
||||
workmanager: ^0.5.2
|
||||
flutter_app_update: ^3.2.2
|
||||
in_app_review: ^2.0.10
|
||||
version: ^3.0.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
25
web/.well-known/apple-app-site-association
Normal file
25
web/.well-known/apple-app-site-association
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"applinks": {
|
||||
"apps": [],
|
||||
"details": [
|
||||
{
|
||||
"appIDs": [
|
||||
"W7HPZ53V6B.dev.solsynth.solian"
|
||||
],
|
||||
"paths": [
|
||||
"*"
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"/": "/*"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"webcredentials": {
|
||||
"apps": [
|
||||
"W7HPZ53V6B.dev.solsynth.solian"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user