Compare commits

..

15 Commits

30 changed files with 526 additions and 405 deletions

View File

@@ -25,8 +25,13 @@ android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions { jvmTarget = JavaVersion.VERSION_17.toString() }
defaultConfig {
applicationId = "dev.solsynth.solian"
// You can update the following values to match your application needs.
@@ -71,16 +76,3 @@ flutter {
source = "../.."
}
kotlin {
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
}
jvmToolchain(21)
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}

View File

@@ -44,83 +44,83 @@ PODS:
- Flutter
- file_saver (0.0.1):
- Flutter
- Firebase/CoreOnly (12.2.0):
- FirebaseCore (~> 12.2.0)
- Firebase/Crashlytics (12.2.0):
- Firebase/CoreOnly (12.4.0):
- FirebaseCore (~> 12.4.0)
- Firebase/Crashlytics (12.4.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 12.2.0)
- Firebase/Messaging (12.2.0):
- FirebaseCrashlytics (~> 12.4.0)
- Firebase/Messaging (12.4.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 12.2.0)
- firebase_analytics (12.0.2):
- FirebaseMessaging (~> 12.4.0)
- firebase_analytics (12.0.3):
- firebase_core
- FirebaseAnalytics (= 12.2.0)
- FirebaseAnalytics (= 12.4.0)
- Flutter
- firebase_core (4.1.1):
- Firebase/CoreOnly (= 12.2.0)
- firebase_core (4.2.0):
- Firebase/CoreOnly (= 12.4.0)
- Flutter
- firebase_crashlytics (5.0.2):
- Firebase/Crashlytics (= 12.2.0)
- firebase_crashlytics (5.0.3):
- Firebase/Crashlytics (= 12.4.0)
- firebase_core
- Flutter
- firebase_messaging (16.0.2):
- Firebase/Messaging (= 12.2.0)
- firebase_messaging (16.0.3):
- Firebase/Messaging (= 12.4.0)
- firebase_core
- Flutter
- FirebaseAnalytics (12.2.0):
- FirebaseAnalytics/Default (= 12.2.0)
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseAnalytics (12.4.0):
- FirebaseAnalytics/Default (= 12.4.0)
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseAnalytics/Default (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- GoogleAppMeasurement/Default (= 12.2.0)
- FirebaseAnalytics/Default (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleAppMeasurement/Default (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseCore (12.2.0):
- FirebaseCoreInternal (~> 12.2.0)
- FirebaseCore (12.4.0):
- FirebaseCoreInternal (~> 12.4.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreExtension (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreInternal (12.2.0):
- FirebaseCoreExtension (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseCoreInternal (12.4.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseCrashlytics (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseRemoteConfigInterop (~> 12.2.0)
- FirebaseSessions (~> 12.2.0)
- FirebaseCrashlytics (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- FirebaseRemoteConfigInterop (~> 12.4.0)
- FirebaseSessions (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- FirebaseInstallations (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (12.4.0):
- FirebaseCore (~> 12.4.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseMessaging (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Reachability (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- FirebaseRemoteConfigInterop (12.2.0)
- FirebaseSessions (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreExtension (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseRemoteConfigInterop (12.4.0)
- FirebaseSessions (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseCoreExtension (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
@@ -157,27 +157,28 @@ PODS:
- gal (1.0.0):
- Flutter
- FlutterMacOS
- GoogleAdsOnDeviceConversion (2.3.0):
- GoogleAdsOnDeviceConversion (3.1.0):
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Core (12.2.0):
- GoogleAppMeasurement/Core (12.4.0):
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Default (12.2.0):
- GoogleAdsOnDeviceConversion (= 2.3.0)
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleAppMeasurement/IdentitySupport (= 12.2.0)
- GoogleAppMeasurement/Default (12.4.0):
- GoogleAdsOnDeviceConversion (~> 3.1.0)
- GoogleAppMeasurement/Core (= 12.4.0)
- GoogleAppMeasurement/IdentitySupport (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/IdentitySupport (12.2.0):
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleAppMeasurement/IdentitySupport (12.4.0):
- GoogleAppMeasurement/Core (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
@@ -486,20 +487,20 @@ SPEC CHECKSUMS:
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
Firebase: 26f6f8d460603af3df970ad505b16b15f5e2e9a1
firebase_analytics: 8c78ce6224e0623152379d6cc7ef3d9098477b7e
firebase_core: dfc4bd142bee4bc53a5d482397ca322c2dd3165d
firebase_crashlytics: e55dcf895eed0dd87c447dd5aff8db7f1bb8bbdb
firebase_messaging: 38c66c1184695b0c87abe51d40fc590718abed1a
FirebaseAnalytics: e04e23bc070e3014aa5cf4980f9df7ce5cd79ec8
FirebaseCore: 311c48a147ad4a0ab7febbaed89e8025c67510cd
FirebaseCoreExtension: 73af080c22a2f7b44cefa391dc08f7e4ee162cb5
FirebaseCoreInternal: 56ea29f3dad2894f81b060f706f9d53509b6ed3b
FirebaseCrashlytics: f83cbf176d5c637ade108c0aacf1ccbd5ec499bf
FirebaseInstallations: 3e884b01feabdf67582a80f3250425a00979b4ed
FirebaseMessaging: 43ec73bbfedd0c385a849bb91593ab4ad4b9e48e
FirebaseRemoteConfigInterop: 0896fd52ab72586a355c8f389ff85aaa9e5375e1
FirebaseSessions: f4692789e770bec66ce17d772c0e9561c4f11737
Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e
firebase_analytics: 1d024068b1d4707d5ba7a42a12976ddf3316d835
firebase_core: 744984dbbed8b3036abf34f0b98d80f130a7e464
firebase_crashlytics: f3a9a4338ab99b67042f64e9e22e1bf349cb44ed
firebase_messaging: 82c70650c426a0a14873e1acdb9ec2b443c4e8b4
FirebaseAnalytics: 0fc2b20091f0ddd21bf73397cf8f0eb5346dc24f
FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3
FirebaseCoreExtension: 7e1f7118ee970e001a8013719fb90950ee5e0018
FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6
FirebaseCrashlytics: a6ece278a837c7e88de2d9b5da0a3542f2342395
FirebaseInstallations: ae9f4902cb5bf1d0c5eaa31ec1f4e5495a0714e2
FirebaseMessaging: d33971b7bb252745ea6cd31ab190d1a1df4b8ed5
FirebaseRemoteConfigInterop: 1e31ec72b89c9924367c59bfb5ec9ab60d1d6766
FirebaseSessions: ba7c7a7ca8696a8d540eb3fe3800fbe98c79786d
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
@@ -512,8 +513,8 @@ SPEC CHECKSUMS:
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
flutter_webrtc: c3e21fc0dcd9d8eb246ae4d5256fcbeb2f5ecd22
gal: baecd024ebfd13c441269ca7404792a7152fde89
GoogleAdsOnDeviceConversion: 9090c435cde08903e8dd1ba2c77fbec9e46d9afe
GoogleAppMeasurement: 09f341dfa8527d1612a09cbfe809a242c0b737af
GoogleAdsOnDeviceConversion: e03a386840803ea7eef3fd22a061930142c039c1
GoogleAppMeasurement: 1e718274b7e015cefd846ac1fcf7820c70dc017d
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a

View File

@@ -114,9 +114,9 @@ final apiClientProvider = Provider<Dio>((ref) {
dio: dio,
retries: 3,
retryDelays: const [
Duration(seconds: 1),
Duration(seconds: 2),
Duration(seconds: 3),
Duration(milliseconds: 300),
Duration(milliseconds: 500),
Duration(milliseconds: 1000),
],
retryEvaluator: (err, _) => err.requestOptions.method == 'GET',
),

View File

@@ -88,6 +88,7 @@ ThemeData createAppTheme(Brightness brightness, AppSettings settings) {
color: colorScheme.surfaceContainer.withOpacity(
settings.cardTransparency,
),
elevation: settings.cardTransparency <= 1 ? 0 : null,
),
pageTransitionsTheme: PageTransitionsTheme(
builders: {

View File

@@ -282,7 +282,11 @@ class AccountScreen extends HookConsumerWidget {
],
),
onTap: () {
context.pushNamed('notifications');
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => const NotificationScreen(),
);
},
),
ListTile(

View File

@@ -20,6 +20,7 @@ class ArticleDetailScreen extends ConsumerWidget {
final articleAsync = ref.watch(articleDetailProvider(articleId));
return AppScaffold(
isNoBackground: false,
body: articleAsync.when(
data:
(article) => AppScaffold(

View File

@@ -54,7 +54,11 @@ Widget notificationIndicatorWidget(
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.only(left: 16, right: 15),
onTap: () {
GoRouter.of(context).pushNamed('notifications');
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => const NotificationScreen(),
);
},
),
);
@@ -330,7 +334,7 @@ class ExploreScreen extends HookConsumerWidget {
),
PostFeaturedList(),
PostComposeCard(
onSubmit: (post) {
onSubmit: () {
activitiesNotifier.forceRefresh();
},
),

View File

@@ -3,7 +3,6 @@ import 'dart:math' as math;
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/account.dart';
@@ -11,8 +10,8 @@ import 'package:island/pods/network.dart';
import 'package:island/pods/websocket.dart';
import 'package:island/route.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/content/markdown.dart';
import 'package:island/widgets/content/sheet.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart';
import 'package:relative_time/relative_time.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -128,19 +127,15 @@ class NotificationScreen extends HookConsumerWidget {
ref.watch(notificationUnreadCountNotifierProvider.notifier).clear();
}
return AppScaffold(
appBar: AppBar(
leading: const PageBackButton(),
title: const Text('notifications').tr(),
return SheetScaffold(
titleText: 'notifications'.tr(),
actions: [
IconButton(
onPressed: markAllRead,
icon: const Icon(Symbols.mark_as_unread),
),
const Gap(8),
],
),
body: PagingHelperView(
child: PagingHelperView(
provider: notificationListNotifierProvider,
futureRefreshable: notificationListNotifierProvider.future,
notifierRefreshable: notificationListNotifierProvider.notifier,

View File

@@ -8,6 +8,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/post.dart';
import 'package:island/models/publisher.dart';
import 'package:island/models/account.dart';
import 'package:island/models/heatmap.dart';
import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart';
import 'package:island/services/color.dart';
@@ -20,6 +21,7 @@ import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/content/cloud_files.dart';
import 'package:island/widgets/content/markdown.dart';
import 'package:island/widgets/post/post_list.dart';
import 'package:island/widgets/activity_heatmap.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:island/services/color_extraction.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -222,6 +224,32 @@ class _PublisherBioWidget extends StatelessWidget {
}
}
class _PublisherHeatmapWidget extends StatelessWidget {
final AsyncValue<SnHeatmap?> heatmap;
final bool forceDense;
const _PublisherHeatmapWidget({
required this.heatmap,
this.forceDense = false,
});
@override
Widget build(BuildContext context) {
return heatmap.when(
data:
(data) =>
data != null
? ActivityHeatmapWidget(
heatmap: data,
forceDense: forceDense,
).padding(horizontal: 8)
: const SizedBox.shrink(),
loading: () => const SizedBox.shrink(),
error: (_, _) => const SizedBox.shrink(),
);
}
}
class _PublisherCategoryTabWidget extends StatelessWidget {
final TabController categoryTabController;
@@ -292,6 +320,13 @@ Future<Color?> publisherAppbarForcegroundColor(Ref ref, String pubName) async {
}
}
@riverpod
Future<SnHeatmap?> publisherHeatmap(Ref ref, String uname) async {
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get('/sphere/publishers/$uname/heatmap');
return SnHeatmap.fromJson(resp.data);
}
class PublisherProfileScreen extends HookConsumerWidget {
final String name;
const PublisherProfileScreen({super.key, required this.name});
@@ -301,6 +336,7 @@ class PublisherProfileScreen extends HookConsumerWidget {
final publisher = ref.watch(publisherProvider(name));
final badges = ref.watch(publisherBadgesProvider(name));
final subStatus = ref.watch(publisherSubscriptionStatusProvider(name));
final heatmap = ref.watch(publisherHeatmapProvider(name));
final appbarColor = ref.watch(
publisherAppbarForcegroundColorProvider(name),
);
@@ -446,6 +482,10 @@ class PublisherProfileScreen extends HookConsumerWidget {
),
_PublisherVerificationWidget(data: data),
_PublisherBioWidget(data: data),
_PublisherHeatmapWidget(
heatmap: heatmap,
forceDense: true,
),
],
),
),
@@ -517,6 +557,9 @@ class PublisherProfileScreen extends HookConsumerWidget {
SliverToBoxAdapter(
child: _PublisherBioWidget(data: data),
),
SliverToBoxAdapter(
child: _PublisherHeatmapWidget(heatmap: heatmap),
),
SliverPostList(pubName: name, pinned: true),
SliverToBoxAdapter(
child: _PublisherCategoryTabWidget(

View File

@@ -530,5 +530,126 @@ class _PublisherAppbarForcegroundColorProviderElement
(origin as PublisherAppbarForcegroundColorProvider).pubName;
}
String _$publisherHeatmapHash() => r'86db275ce3861a2855b5ec35fbfef85fc47b23a6';
/// See also [publisherHeatmap].
@ProviderFor(publisherHeatmap)
const publisherHeatmapProvider = PublisherHeatmapFamily();
/// See also [publisherHeatmap].
class PublisherHeatmapFamily extends Family<AsyncValue<SnHeatmap?>> {
/// See also [publisherHeatmap].
const PublisherHeatmapFamily();
/// See also [publisherHeatmap].
PublisherHeatmapProvider call(String uname) {
return PublisherHeatmapProvider(uname);
}
@override
PublisherHeatmapProvider getProviderOverride(
covariant PublisherHeatmapProvider provider,
) {
return call(provider.uname);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'publisherHeatmapProvider';
}
/// See also [publisherHeatmap].
class PublisherHeatmapProvider extends AutoDisposeFutureProvider<SnHeatmap?> {
/// See also [publisherHeatmap].
PublisherHeatmapProvider(String uname)
: this._internal(
(ref) => publisherHeatmap(ref as PublisherHeatmapRef, uname),
from: publisherHeatmapProvider,
name: r'publisherHeatmapProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$publisherHeatmapHash,
dependencies: PublisherHeatmapFamily._dependencies,
allTransitiveDependencies:
PublisherHeatmapFamily._allTransitiveDependencies,
uname: uname,
);
PublisherHeatmapProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.uname,
}) : super.internal();
final String uname;
@override
Override overrideWith(
FutureOr<SnHeatmap?> Function(PublisherHeatmapRef provider) create,
) {
return ProviderOverride(
origin: this,
override: PublisherHeatmapProvider._internal(
(ref) => create(ref as PublisherHeatmapRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
uname: uname,
),
);
}
@override
AutoDisposeFutureProviderElement<SnHeatmap?> createElement() {
return _PublisherHeatmapProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is PublisherHeatmapProvider && other.uname == uname;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, uname.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin PublisherHeatmapRef on AutoDisposeFutureProviderRef<SnHeatmap?> {
/// The parameter `uname` of this provider.
String get uname;
}
class _PublisherHeatmapProviderElement
extends AutoDisposeFutureProviderElement<SnHeatmap?>
with PublisherHeatmapRef {
_PublisherHeatmapProviderElement(super.provider);
@override
String get uname => (origin as PublisherHeatmapProvider).uname;
}
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

View File

@@ -66,12 +66,12 @@ class TabsScreen extends HookConsumerWidget {
if (wideScreen)
NavigationDestination(
label: 'creatorHub'.tr(),
icon: const Icon(Symbols.draw),
icon: const Icon(Symbols.ink_pen),
),
if (wideScreen)
NavigationDestination(
label: 'developerHub'.tr(),
icon: const Icon(Symbols.code),
icon: const Icon(Symbols.data_object),
),
];
@@ -126,6 +126,7 @@ class TabsScreen extends HookConsumerWidget {
return Scaffold(
backgroundColor: Colors.transparent,
extendBody: true,
resizeToAvoidBottomInset: false,
body: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),

View File

@@ -99,7 +99,7 @@ class EventDetailsWidget extends StatelessWidget {
],
),
if (event?.checkInResult == null && (event?.statuses.isEmpty ?? true))
Text('eventCalandarEmpty').tr(),
Text('eventCalendarEmpty').tr(),
],
).padding(vertical: 24, horizontal: 24);
}

View File

@@ -11,8 +11,13 @@ import '../services/responsive.dart';
/// Shows exactly 365 days (wide screen) or 90 days (non-wide screen) of data ending at the current date.
class ActivityHeatmapWidget extends HookConsumerWidget {
final SnHeatmap heatmap;
final bool forceDense;
const ActivityHeatmapWidget({super.key, required this.heatmap});
const ActivityHeatmapWidget({
super.key,
required this.heatmap,
this.forceDense = false,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -21,7 +26,7 @@ class ActivityHeatmapWidget extends HookConsumerWidget {
final now = DateTime.now();
final isWide = isWideScreen(context);
final days = isWide ? 365 : 90;
final days = (isWide && !forceDense) ? 365 : 90;
// Start from exactly the selected days ago
final startDate = now.subtract(Duration(days: days));

View File

@@ -314,28 +314,22 @@ class AppScaffold extends HookConsumerWidget {
final noBackground = isNoBackground ?? isWideScreen(context);
final content = Column(
children: [
IgnorePointer(
child: SizedBox(height: appBar != null ? appBarHeight + safeTop : 0),
),
if (body != null) Expanded(child: body!),
],
);
return Focus(
final builtWidget = Focus(
focusNode: focusNode,
child: Scaffold(
extendBody: extendBody ?? true,
extendBodyBehindAppBar: true,
backgroundColor:
noBackground
? Colors.transparent
: Theme.of(context).scaffoldBackgroundColor,
body:
noBackground
? content
: AppBackground(isRoot: true, child: content),
backgroundColor: Colors.transparent,
body: Column(
children: [
IgnorePointer(
child: SizedBox(
height: appBar != null ? appBarHeight + safeTop : 0,
),
),
if (body != null) Expanded(child: body!),
],
),
appBar: appBar,
bottomNavigationBar: bottomNavigationBar,
bottomSheet: bottomSheet,
@@ -348,6 +342,10 @@ class AppScaffold extends HookConsumerWidget {
onEndDrawerChanged: onEndDrawerChanged,
),
);
return noBackground
? builtWidget
: AppBackground(isRoot: true, child: builtWidget);
}
}

View File

@@ -73,10 +73,8 @@ class ChatInput extends HookConsumerWidget {
final chatSubscribe = ref.watch(chatSubscribeNotifierProvider(chatRoom.id));
void send() {
onSend.call();
WidgetsBinding.instance.addPostFrameCallback((_) {
inputFocusNode.requestFocus();
});
onSend.call();
}
void insertNewLine() {
@@ -120,6 +118,8 @@ class ChatInput extends HookConsumerWidget {
}
}
final settings = ref.watch(appSettingsNotifierProvider);
inputFocusNode.onKeyEvent = (node, event) {
if (event is! KeyDownEvent) return KeyEventResult.ignored;
@@ -133,7 +133,7 @@ class ChatInput extends HookConsumerWidget {
return KeyEventResult.handled;
}
final enterToSend = ref.read(appSettingsNotifierProvider).enterToSend;
final enterToSend = settings.enterToSend;
final isEnter = event.logicalKey == LogicalKeyboardKey.enter;
if (isEnter) {
@@ -467,24 +467,28 @@ class ChatInput extends HookConsumerWidget {
),
UploadMenu(
items: [
MenuItemData(
UploadMenuItemData(
Symbols.add_a_photo,
'addPhoto',
() => onPickFile(true),
),
MenuItemData(
UploadMenuItemData(
Symbols.videocam,
'addVideo',
() => onPickFile(false),
),
MenuItemData(Symbols.mic, 'addAudio', onPickAudio),
MenuItemData(
UploadMenuItemData(
Symbols.mic,
'addAudio',
onPickAudio,
),
UploadMenuItemData(
Symbols.file_upload,
'uploadFile',
onPickGeneralFile,
),
if (onLinkAttachment != null)
MenuItemData(
UploadMenuItemData(
Symbols.attach_file,
'linkAttachment',
onLinkAttachment!,
@@ -528,11 +532,17 @@ class ChatInput extends HookConsumerWidget {
? '${messageController.text.length}/4096'
: null,
),
maxLines: 3,
maxLines: 5,
minLines: 1,
onTapOutside:
(_) =>
FocusManager.instance.primaryFocus?.unfocus(),
textInputAction:
settings.enterToSend
? TextInputAction.send
: null,
onSubmitted:
settings.enterToSend ? (_) => send() : null,
);
},
suggestionsCallback: (pattern) async {
@@ -542,11 +552,13 @@ class ChatInput extends HookConsumerWidget {
final triggerIndex =
atIndex > colonIndex ? atIndex : colonIndex;
if (triggerIndex == -1) return [];
final chopped = pattern.substring(triggerIndex);
if (chopped.contains(' ')) return [];
final service = ref.read(autocompleteServiceProvider);
try {
return await service.getSuggestions(
chatRoom.id,
pattern,
chopped,
);
} catch (e) {
return [];
@@ -637,7 +649,7 @@ class ChatInput extends HookConsumerWidget {
direction: VerticalDirection.up,
hideOnEmpty: true,
hideOnLoading: true,
debounceDuration: const Duration(milliseconds: 500),
debounceDuration: const Duration(milliseconds: 1000),
),
),
IconButton(

View File

@@ -161,6 +161,7 @@ class MessageItem extends HookConsumerWidget {
clipBehavior: Clip.none,
children: [
SwipeTo(
swipeSensitivity: 15,
rightSwipeWidget: Transform.flip(
flipX: true,
child: Icon(Symbols.menu_open),
@@ -477,6 +478,8 @@ class _MessageActionSheetState extends State<MessageActionSheet> {
Navigator.pop(context);
},
),
Gap(MediaQuery.of(context).padding.bottom),
],
),
),

View File

@@ -34,9 +34,9 @@ class PostComposeCard extends HookConsumerWidget {
final SnPost? originalPost;
final PostComposeInitialState? initialState;
final VoidCallback? onCancel;
final Function(SnPost)? onSubmit;
final Function()? onSubmit;
final Function(ComposeState)? onStateChanged;
final bool isInDialog;
final bool isDialog;
const PostComposeCard({
super.key,
@@ -45,7 +45,7 @@ class PostComposeCard extends HookConsumerWidget {
this.onCancel,
this.onSubmit,
this.onStateChanged,
this.isInDialog = false,
this.isDialog = false,
});
@override
@@ -164,20 +164,19 @@ class PostComposeCard extends HookConsumerWidget {
// Reset the form for new composition
ComposeStateUtils.resetForm(state);
// Call the widget's onSubmit callback to trigger activity list refresh
// Note: onSubmit still receives the post from the return value
onSubmit?.call();
},
);
}
final maxHeight = math.min(
640.0,
MediaQuery.of(context).size.height * (isInDialog ? 0.8 : 0.72),
MediaQuery.of(context).size.height * (isDialog ? 0.8 : 0.72),
);
return Card(
margin: EdgeInsets.zero,
color: Theme.of(context).colorScheme.surfaceContainer,
color: isDialog ? Theme.of(context).colorScheme.surfaceContainer : null,
child: Container(
constraints: BoxConstraints(maxHeight: maxHeight),
child: Column(
@@ -311,7 +310,7 @@ class PostComposeCard extends HookConsumerWidget {
onTap: () {
if (state.currentPublisher.value == null) {
// No publisher loaded, guide user to create one
if (isInDialog) {
if (isDialog) {
Navigator.of(context).pop();
}
context.pushNamed('creatorNew').then((value) {
@@ -348,7 +347,7 @@ class PostComposeCard extends HookConsumerWidget {
onPublisherTap: () {
if (state.currentPublisher.value == null) {
// No publisher loaded, guide user to create one
if (isInDialog) {
if (isDialog) {
Navigator.of(context).pop();
}
context.pushNamed('creatorNew').then((

View File

@@ -23,12 +23,12 @@ class PostComposeDialog extends HookConsumerWidget {
this.isBottomSheet = false,
});
static Future<SnPost?> show(
static Future<bool?> show(
BuildContext context, {
SnPost? originalPost,
PostComposeInitialState? initialState,
}) {
return showDialog<SnPost>(
return showDialog<bool>(
context: context,
useRootNavigator: true,
builder:
@@ -74,8 +74,8 @@ class PostComposeDialog extends HookConsumerWidget {
originalPost: originalPost,
initialState: restoredInitialState.value ?? initialState,
onCancel: () => Navigator.of(context).pop(),
onSubmit: (post) => Navigator.of(context).pop(post),
isInDialog: true,
onSubmit: () => Navigator.of(context).pop(true),
isDialog: true,
),
),
);

View File

@@ -149,9 +149,11 @@ class ComposeFormFields extends HookConsumerWidget {
final triggerIndex =
atIndex > colonIndex ? atIndex : colonIndex;
if (triggerIndex == -1) return [];
final chopped = pattern.substring(triggerIndex);
if (chopped.contains(' ')) return [];
final service = ref.read(autocompleteServiceProvider);
try {
return await service.getGeneralSuggestions(pattern);
return await service.getGeneralSuggestions(chopped);
} catch (e) {
return [];
}
@@ -235,7 +237,7 @@ class ComposeFormFields extends HookConsumerWidget {
direction: VerticalDirection.down,
hideOnEmpty: true,
hideOnLoading: true,
debounceDuration: const Duration(milliseconds: 500),
debounceDuration: const Duration(milliseconds: 1000),
),
],
),

View File

@@ -16,7 +16,6 @@ import 'package:island/widgets/post/compose_shared.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:textfield_tags/textfield_tags.dart';
part 'compose_settings_sheet.g.dart';
@@ -37,98 +36,6 @@ Future<List<SnPostCategory>> postCategories(Ref ref) async {
return uniqueCategories.values.toList();
}
/// A reusable widget for tag input fields with chip display
class ChipTagInputField extends StatelessWidget {
final InputFieldValues inputFieldValues;
final String labelText;
final String hintText;
const ChipTagInputField({
super.key,
required this.inputFieldValues,
required this.labelText,
required this.hintText,
});
@override
Widget build(BuildContext context) {
return TextField(
controller: inputFieldValues.textEditingController,
focusNode: inputFieldValues.focusNode,
decoration: InputDecoration(
label: Text(labelText).tr(),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
contentPadding: const EdgeInsets.all(16),
hintText: inputFieldValues.tags.isNotEmpty ? '' : hintText.tr(),
errorText: inputFieldValues.error,
prefixIconConstraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.8,
),
prefixIcon:
inputFieldValues.tags.isNotEmpty
? SingleChildScrollView(
controller: inputFieldValues.tagScrollController,
scrollDirection: Axis.vertical,
child: Padding(
padding: const EdgeInsets.only(top: 8, bottom: 8, left: 8),
child: Wrap(
runSpacing: 4.0,
spacing: 4.0,
children:
inputFieldValues.tags.map<Widget>((dynamic tag) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
color: Theme.of(context).colorScheme.primary,
),
margin: const EdgeInsets.only(left: 5),
padding: const EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 5.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
InkWell(
child: Text(
'#$tag',
style: TextStyle(
color:
Theme.of(
context,
).colorScheme.onPrimary,
),
),
),
const Gap(4),
InkWell(
child: const Icon(
Icons.cancel,
size: 14.0,
color: Color.fromARGB(255, 233, 233, 233),
),
onTap: () {
inputFieldValues.onTagRemoved(tag);
},
),
],
),
);
}).toList(),
),
),
)
: null,
),
onChanged: inputFieldValues.onTagChanged,
onSubmitted: inputFieldValues.onTagSubmitted,
);
}
}
class ComposeSettingsSheet extends HookConsumerWidget {
final ComposeState state;

View File

@@ -82,10 +82,10 @@ class ComposeToolbar extends HookConsumerWidget {
}
final uploadMenuItems = [
MenuItemData(Symbols.add_a_photo, 'addPhoto', pickPhotoMedia),
MenuItemData(Symbols.videocam, 'addVideo', pickVideoMedia),
MenuItemData(Symbols.mic, 'addAudio', addAudio),
MenuItemData(Symbols.file_upload, 'uploadFile', pickGeneralFile),
UploadMenuItemData(Symbols.add_a_photo, 'addPhoto', pickPhotoMedia),
UploadMenuItemData(Symbols.videocam, 'addVideo', pickVideoMedia),
UploadMenuItemData(Symbols.mic, 'addAudio', addAudio),
UploadMenuItemData(Symbols.file_upload, 'uploadFile', pickGeneralFile),
];
final colorScheme = Theme.of(context).colorScheme;

View File

@@ -334,7 +334,7 @@ class PostActionableItem extends HookConsumerWidget {
);
},
child: Material(
color: Theme.of(context).colorScheme.surfaceContainerLow,
color: Theme.of(context).cardTheme.color,
borderRadius:
borderRadius != null
? BorderRadius.all(Radius.circular(borderRadius!))

View File

@@ -23,6 +23,7 @@ class PostListNotifier extends _$PostListNotifier
List<String>? tags,
bool? pinned,
bool shuffle = false,
bool? includeReplies,
}) {
return fetch(cursor: null);
}
@@ -42,6 +43,7 @@ class PostListNotifier extends _$PostListNotifier
if (categories != null) 'categories': categories,
if (shuffle) 'shuffle': true,
if (pinned != null) 'pinned': pinned,
if (includeReplies != null) 'includeReplies': includeReplies,
};
final response = await client.get(

View File

@@ -6,7 +6,7 @@ part of 'post_list.dart';
// RiverpodGenerator
// **************************************************************************
String _$postListNotifierHash() => r'3c0a8154ded4bcd8f5456f7a4ea2e542f57efa85';
String _$postListNotifierHash() => r'fc139ad4df0deb67bcbb949560319f2f7fbfb503';
/// Copied from Dart SDK
class _SystemHash {
@@ -38,6 +38,7 @@ abstract class _$PostListNotifier
late final List<String>? tags;
late final bool? pinned;
late final bool shuffle;
late final bool? includeReplies;
FutureOr<CursorPagingData<SnPost>> build({
String? pubName,
@@ -47,6 +48,7 @@ abstract class _$PostListNotifier
List<String>? tags,
bool? pinned,
bool shuffle = false,
bool? includeReplies,
});
}
@@ -69,6 +71,7 @@ class PostListNotifierFamily
List<String>? tags,
bool? pinned,
bool shuffle = false,
bool? includeReplies,
}) {
return PostListNotifierProvider(
pubName: pubName,
@@ -78,6 +81,7 @@ class PostListNotifierFamily
tags: tags,
pinned: pinned,
shuffle: shuffle,
includeReplies: includeReplies,
);
}
@@ -93,6 +97,7 @@ class PostListNotifierFamily
tags: provider.tags,
pinned: provider.pinned,
shuffle: provider.shuffle,
includeReplies: provider.includeReplies,
);
}
@@ -127,6 +132,7 @@ class PostListNotifierProvider
List<String>? tags,
bool? pinned,
bool shuffle = false,
bool? includeReplies,
}) : this._internal(
() =>
PostListNotifier()
@@ -136,7 +142,8 @@ class PostListNotifierProvider
..categories = categories
..tags = tags
..pinned = pinned
..shuffle = shuffle,
..shuffle = shuffle
..includeReplies = includeReplies,
from: postListNotifierProvider,
name: r'postListNotifierProvider',
debugGetCreateSourceHash:
@@ -153,6 +160,7 @@ class PostListNotifierProvider
tags: tags,
pinned: pinned,
shuffle: shuffle,
includeReplies: includeReplies,
);
PostListNotifierProvider._internal(
@@ -169,6 +177,7 @@ class PostListNotifierProvider
required this.tags,
required this.pinned,
required this.shuffle,
required this.includeReplies,
}) : super.internal();
final String? pubName;
@@ -178,6 +187,7 @@ class PostListNotifierProvider
final List<String>? tags;
final bool? pinned;
final bool shuffle;
final bool? includeReplies;
@override
FutureOr<CursorPagingData<SnPost>> runNotifierBuild(
@@ -191,6 +201,7 @@ class PostListNotifierProvider
tags: tags,
pinned: pinned,
shuffle: shuffle,
includeReplies: includeReplies,
);
}
@@ -207,7 +218,8 @@ class PostListNotifierProvider
..categories = categories
..tags = tags
..pinned = pinned
..shuffle = shuffle,
..shuffle = shuffle
..includeReplies = includeReplies,
from: from,
name: null,
dependencies: null,
@@ -220,6 +232,7 @@ class PostListNotifierProvider
tags: tags,
pinned: pinned,
shuffle: shuffle,
includeReplies: includeReplies,
),
);
}
@@ -242,7 +255,8 @@ class PostListNotifierProvider
other.categories == categories &&
other.tags == tags &&
other.pinned == pinned &&
other.shuffle == shuffle;
other.shuffle == shuffle &&
other.includeReplies == includeReplies;
}
@override
@@ -255,6 +269,7 @@ class PostListNotifierProvider
hash = _SystemHash.combine(hash, tags.hashCode);
hash = _SystemHash.combine(hash, pinned.hashCode);
hash = _SystemHash.combine(hash, shuffle.hashCode);
hash = _SystemHash.combine(hash, includeReplies.hashCode);
return _SystemHash.finish(hash);
}
@@ -284,6 +299,9 @@ mixin PostListNotifierRef
/// The parameter `shuffle` of this provider.
bool get shuffle;
/// The parameter `includeReplies` of this provider.
bool? get includeReplies;
}
class _PostListNotifierProviderElement
@@ -310,6 +328,9 @@ class _PostListNotifierProviderElement
bool? get pinned => (origin as PostListNotifierProvider).pinned;
@override
bool get shuffle => (origin as PostListNotifierProvider).shuffle;
@override
bool? get includeReplies =>
(origin as PostListNotifierProvider).includeReplies;
}
// ignore_for_file: type=lint

View File

@@ -68,21 +68,24 @@ class PostQuickReply extends HookConsumerWidget {
}
}
const kInputChipHeight = 54.0;
return publishers.when(
data:
(data) => Material(
elevation: 2,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(20),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 8),
borderRadius: BorderRadius.circular(28),
child: Container(
constraints: BoxConstraints(minHeight: kInputChipHeight),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
child: ProfilePictureWidget(
fileId: currentPublisher.value?.picture?.id,
radius: 16,
radius: (kInputChipHeight * 0.5) - 6,
),
onTap: () {
showModalBottomSheet(
@@ -106,11 +109,13 @@ class PostQuickReply extends HookConsumerWidget {
isCollapsed: true,
contentPadding: EdgeInsets.symmetric(
horizontal: 12,
vertical: 9,
vertical: 14,
),
visualDensity: VisualDensity.compact,
),
style: TextStyle(fontSize: 14),
maxLines: null,
minLines: 1,
maxLines: 5,
onTapOutside:
(_) => FocusManager.instance.primaryFocus?.unfocus(),
),
@@ -130,6 +135,10 @@ class PostQuickReply extends HookConsumerWidget {
},
icon: const Icon(Symbols.launch, size: 20),
visualDensity: VisualDensity.compact,
constraints: BoxConstraints(
maxHeight: kInputChipHeight - 6,
minHeight: kInputChipHeight - 6,
),
),
IconButton(
icon:
@@ -143,6 +152,10 @@ class PostQuickReply extends HookConsumerWidget {
color: Theme.of(context).colorScheme.primary,
onPressed: submitting.value ? null : performAction,
visualDensity: VisualDensity.compact,
constraints: BoxConstraints(
maxHeight: kInputChipHeight - 6,
minHeight: kInputChipHeight - 6,
),
),
],
),

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/post.dart';
import 'package:island/pods/userinfo.dart';
@@ -19,11 +20,9 @@ class PostRepliesSheet extends HookConsumerWidget {
return SheetScaffold(
titleText: 'repliesCount'.plural(post.repliesCount),
child: Column(
child: Stack(
children: [
// Replies list
Expanded(
child: CustomScrollView(
CustomScrollView(
slivers: [
PostRepliesList(
postId: post.id.toString(),
@@ -31,12 +30,15 @@ class PostRepliesSheet extends HookConsumerWidget {
Navigator.pop(context);
},
),
SliverGap(80),
],
),
),
// Quick reply section
if (user.value != null)
PostQuickReply(
Positioned(
bottom: 0,
left: 0,
right: 0,
child: PostQuickReply(
parent: post,
onPosted: () {
ref.invalidate(postRepliesNotifierProvider(post.id));
@@ -49,6 +51,7 @@ class PostRepliesSheet extends HookConsumerWidget {
top: 8,
horizontal: 16,
),
),
],
),
);

View File

@@ -2,16 +2,16 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';
class MenuItemData {
class UploadMenuItemData {
final IconData icon;
final String textKey;
final VoidCallback onPressed;
const MenuItemData(this.icon, this.textKey, this.onPressed);
const UploadMenuItemData(this.icon, this.textKey, this.onPressed);
}
class UploadMenu extends StatelessWidget {
final List<MenuItemData> items;
final List<UploadMenuItemData> items;
final bool isCompact;
final Color? iconColor;
@@ -51,6 +51,7 @@ class UploadMenu extends StatelessWidget {
onPressed: item.onPressed,
leadingIcon: Icon(item.icon),
style: ButtonStyle(
visualDensity: VisualDensity.compact,
padding: WidgetStatePropertyAll(
EdgeInsets.only(left: 12, right: 16, top: 20, bottom: 20),
),

View File

@@ -13,85 +13,85 @@ PODS:
- FlutterMacOS
- file_selector_macos (0.0.1):
- FlutterMacOS
- Firebase/CoreOnly (12.2.0):
- FirebaseCore (~> 12.2.0)
- Firebase/Crashlytics (12.2.0):
- Firebase/CoreOnly (12.4.0):
- FirebaseCore (~> 12.4.0)
- Firebase/Crashlytics (12.4.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 12.2.0)
- Firebase/Messaging (12.2.0):
- FirebaseCrashlytics (~> 12.4.0)
- Firebase/Messaging (12.4.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 12.2.0)
- firebase_analytics (12.0.2):
- FirebaseMessaging (~> 12.4.0)
- firebase_analytics (12.0.3):
- firebase_core
- FirebaseAnalytics (= 12.2.0)
- FirebaseAnalytics (= 12.4.0)
- FlutterMacOS
- firebase_core (4.1.1):
- Firebase/CoreOnly (~> 12.2.0)
- firebase_core (4.2.0):
- Firebase/CoreOnly (~> 12.4.0)
- FlutterMacOS
- firebase_crashlytics (5.0.2):
- Firebase/CoreOnly (~> 12.2.0)
- Firebase/Crashlytics (~> 12.2.0)
- firebase_crashlytics (5.0.3):
- Firebase/CoreOnly (~> 12.4.0)
- Firebase/Crashlytics (~> 12.4.0)
- firebase_core
- FlutterMacOS
- firebase_messaging (16.0.2):
- Firebase/CoreOnly (~> 12.2.0)
- Firebase/Messaging (~> 12.2.0)
- firebase_messaging (16.0.3):
- Firebase/CoreOnly (~> 12.4.0)
- Firebase/Messaging (~> 12.4.0)
- firebase_core
- FlutterMacOS
- FirebaseAnalytics (12.2.0):
- FirebaseAnalytics/Default (= 12.2.0)
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseAnalytics (12.4.0):
- FirebaseAnalytics/Default (= 12.4.0)
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseAnalytics/Default (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- GoogleAppMeasurement/Default (= 12.2.0)
- FirebaseAnalytics/Default (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleAppMeasurement/Default (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseCore (12.2.0):
- FirebaseCoreInternal (~> 12.2.0)
- FirebaseCore (12.4.0):
- FirebaseCoreInternal (~> 12.4.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreExtension (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreInternal (12.2.0):
- FirebaseCoreExtension (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseCoreInternal (12.4.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseCrashlytics (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseRemoteConfigInterop (~> 12.2.0)
- FirebaseSessions (~> 12.2.0)
- FirebaseCrashlytics (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- FirebaseRemoteConfigInterop (~> 12.4.0)
- FirebaseSessions (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- FirebaseInstallations (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (12.4.0):
- FirebaseCore (~> 12.4.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseMessaging (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Reachability (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- FirebaseRemoteConfigInterop (12.2.0)
- FirebaseSessions (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreExtension (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseRemoteConfigInterop (12.4.0)
- FirebaseSessions (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseCoreExtension (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
@@ -118,23 +118,23 @@ PODS:
- gal (1.0.0):
- Flutter
- FlutterMacOS
- GoogleAppMeasurement/Core (12.2.0):
- GoogleAppMeasurement/Core (12.4.0):
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Default (12.2.0):
- GoogleAdsOnDeviceConversion (= 2.3.0)
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleAppMeasurement/IdentitySupport (= 12.2.0)
- GoogleAppMeasurement/Default (12.4.0):
- GoogleAdsOnDeviceConversion (~> 3.1.0)
- GoogleAppMeasurement/Core (= 12.4.0)
- GoogleAppMeasurement/IdentitySupport (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/IdentitySupport (12.2.0):
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleAppMeasurement/IdentitySupport (12.4.0):
- GoogleAppMeasurement/Core (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
@@ -416,20 +416,20 @@ SPEC CHECKSUMS:
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
file_saver: e35bd97de451dde55ff8c38862ed7ad0f3418d0f
file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31
Firebase: 26f6f8d460603af3df970ad505b16b15f5e2e9a1
firebase_analytics: 26346c2ccb9ba410c2f33d5d34c62e6369cbbf29
firebase_core: 54fd706197e1779d510b297548eee74d3b39577c
firebase_crashlytics: 3694b4aca0849f6919244d7bbbb40615f989f46b
firebase_messaging: 658f1a6906d80faec2fb20e3aadb81af6b09e441
FirebaseAnalytics: e04e23bc070e3014aa5cf4980f9df7ce5cd79ec8
FirebaseCore: 311c48a147ad4a0ab7febbaed89e8025c67510cd
FirebaseCoreExtension: 73af080c22a2f7b44cefa391dc08f7e4ee162cb5
FirebaseCoreInternal: 56ea29f3dad2894f81b060f706f9d53509b6ed3b
FirebaseCrashlytics: f83cbf176d5c637ade108c0aacf1ccbd5ec499bf
FirebaseInstallations: 3e884b01feabdf67582a80f3250425a00979b4ed
FirebaseMessaging: 43ec73bbfedd0c385a849bb91593ab4ad4b9e48e
FirebaseRemoteConfigInterop: 0896fd52ab72586a355c8f389ff85aaa9e5375e1
FirebaseSessions: f4692789e770bec66ce17d772c0e9561c4f11737
Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e
firebase_analytics: d876586269c1d8d2b3dcac085bc2d97c62abc9df
firebase_core: d81d1a44df95699ce074ae63d8cb43e9df21e142
firebase_crashlytics: 723622cc39a9fa7320585424f5864c5699893ce1
firebase_messaging: 31f412ae5a54e02d1c46d467969f7ad92c4b81ec
FirebaseAnalytics: 0fc2b20091f0ddd21bf73397cf8f0eb5346dc24f
FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3
FirebaseCoreExtension: 7e1f7118ee970e001a8013719fb90950ee5e0018
FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6
FirebaseCrashlytics: a6ece278a837c7e88de2d9b5da0a3542f2342395
FirebaseInstallations: ae9f4902cb5bf1d0c5eaa31ec1f4e5495a0714e2
FirebaseMessaging: d33971b7bb252745ea6cd31ab190d1a1df4b8ed5
FirebaseRemoteConfigInterop: 1e31ec72b89c9924367c59bfb5ec9ab60d1d6766
FirebaseSessions: ba7c7a7ca8696a8d540eb3fe3800fbe98c79786d
flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d
flutter_local_notifications: 4bf37a31afde695b56091b4ae3e4d9c7a7e6cda0
flutter_platform_alert: 8fa7a7c21f95b26d08b4a3891936ca27e375f284
@@ -439,7 +439,7 @@ SPEC CHECKSUMS:
flutter_webrtc: 718eae22a371cd94e5d56aa4f301443ebc5bb737
FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1
gal: baecd024ebfd13c441269ca7404792a7152fde89
GoogleAppMeasurement: 09f341dfa8527d1612a09cbfe809a242c0b737af
GoogleAppMeasurement: 1e718274b7e015cefd846ac1fcf7820c70dc017d
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
irondash_engine_context: 893c7d96d20ce361d7e996f39d360c4c2f9869ba

View File

@@ -13,10 +13,10 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "23d16f00a2da8ffa997c782453c73867b0609bd90435195671a54de38a3566df"
sha256: f871a7d1b686bea1f13722aa51ab31554d05c81f47054d6de48cc8c45153508b
url: "https://pub.dev"
source: hosted
version: "1.3.62"
version: "1.3.63"
analyzer:
dependency: transitive
description:
@@ -629,90 +629,90 @@ packages:
dependency: "direct main"
description:
name: firebase_analytics
sha256: fce78440ab7b95563054039aac5e342088efed9dc009ac6f81d5cac07155d509
sha256: "3cfc4089e61e810ffb531af63cfde2c8cfd36f12dc14fdba359e623992311015"
url: "https://pub.dev"
source: hosted
version: "12.0.2"
version: "12.0.3"
firebase_analytics_platform_interface:
dependency: transitive
description:
name: firebase_analytics_platform_interface
sha256: "75bdcd2d2635c4cdcd7ec13727527751ddf2f9933e5bf1264a2387920246f3c5"
sha256: "775fc18d9b00a014362510a33f76f1f34deb30f69a64edcb41a7dfd0ebd9cf98"
url: "https://pub.dev"
source: hosted
version: "5.0.2"
version: "5.0.3"
firebase_analytics_web:
dependency: transitive
description:
name: firebase_analytics_web
sha256: ed5767695b131cdd425ee6d49934dca80689d9df40609c0d0aa8907ee6f0f785
sha256: "6eafa8fef5fdca6c922ac3e353c9a093c12344a3ba996e65fd40f8db0a00d26f"
url: "https://pub.dev"
source: hosted
version: "0.6.0+2"
version: "0.6.0+3"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
sha256: "4dd96f05015c0dcceaa47711394c32971aee70169625d5e2477e7676c01ce0ee"
sha256: "132e1c311bc41e7d387b575df0aacdf24efbf4930365eb61042be5bde3978f03"
url: "https://pub.dev"
source: hosted
version: "4.1.1"
version: "4.2.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: "5873a370f0d232918e23a5a6137dbe4c2c47cf017301f4ea02d9d636e52f60f0"
sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64
url: "https://pub.dev"
source: hosted
version: "6.0.1"
version: "6.0.2"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: "61a51037312dac781f713308903bb7a1762a7f92f7bc286a3a0947fb2a713b82"
sha256: ecde2def458292404a4fcd3731ee4992fd631a0ec359d2d67c33baa8da5ec8ae
url: "https://pub.dev"
source: hosted
version: "3.1.1"
version: "3.2.0"
firebase_crashlytics:
dependency: "direct main"
description:
name: firebase_crashlytics
sha256: a636096df0d2a4bc72397bfc669a4fffc8896016a58de1a6f45a49d9ba064f94
sha256: "2f53d0d3c0875105b166f09bdf026026bb74f26930c6ffcd5d65b311ca5a9f58"
url: "https://pub.dev"
source: hosted
version: "5.0.2"
version: "5.0.3"
firebase_crashlytics_platform_interface:
dependency: transitive
description:
name: firebase_crashlytics_platform_interface
sha256: "1ccad077a6fc7bace97d8eace263f42e66dc23a23a839de864a4f10ac4a7c264"
sha256: de5c857525fc9576cd3fc30fc72422bc2371179ecae110246c0135ae896c6de3
url: "https://pub.dev"
source: hosted
version: "3.8.13"
version: "3.8.14"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
sha256: ba12ad0b600e0c939fbb9391e1cd3320a5b5dad5284276b9182fc21eb1e72c2b
sha256: "5021279acd1cb5ccaceaa388e616e82cc4a2e4d862f02637df0e8ab766e6900a"
url: "https://pub.dev"
source: hosted
version: "16.0.2"
version: "16.0.3"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
sha256: b4bade67bfc09fcc56eb012b3fc72b59ca9e2259a34cdfb81b368169770ff536
sha256: f3a16c51f02055ace2a7c16ccb341c1f1b36b67c13270a48bcef68c1d970bbe8
url: "https://pub.dev"
source: hosted
version: "4.7.2"
version: "4.7.3"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
sha256: "8ae4a00d178993feb79603cad324b53696375cbb78805e8eb603fe331866629d"
sha256: "3eb9a1382caeb95b370f21e36d4a460496af777c9c2ef5df9b90d4803982c069"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
version: "4.0.3"
fixnum:
dependency: transitive
description:
@@ -770,10 +770,10 @@ packages:
dependency: "direct main"
description:
name: flutter_card_swiper
sha256: "1eacbfab31b572223042e03409726553aec431abe48af48c8d591d376d070d3d"
sha256: "9fbe75c913c0a01f34f9f98068ad198e396695fcf8abfa433cc53652fceb5617"
url: "https://pub.dev"
source: hosted
version: "7.0.2"
version: "7.1.0"
flutter_colorpicker:
dependency: "direct main"
description:
@@ -1992,10 +1992,11 @@ packages:
receive_sharing_intent:
dependency: "direct main"
description:
name: receive_sharing_intent
sha256: ec76056e4d258ad708e76d85591d933678625318e411564dcb9059048ca3a593
url: "https://pub.dev"
source: hosted
path: "."
ref: master
resolved-ref: "2cea396843cd3ab1b5ec4334be4233864637874e"
url: "https://github.com/KasemJaffer/receive_sharing_intent"
source: git
version: "1.8.1"
record:
dependency: "direct main"
@@ -2430,10 +2431,10 @@ packages:
dependency: transitive
description:
name: sqlite3
sha256: "809bc27297bd0633ef360a7e27e056e93a2ef598079616db97b0c93e275f6d31"
sha256: f18fd9a72d7a1ad2920db61368f2a69368f1cc9b56b8233e9d83b47b0a8435aa
url: "https://pub.dev"
source: hosted
version: "2.9.2"
version: "2.9.3"
sqlite3_flutter_libs:
dependency: transitive
description:
@@ -2674,15 +2675,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.6"
textfield_tags:
dependency: "direct main"
description:
path: "."
ref: "fixes/allow-controller-re-registration"
resolved-ref: "7574e79649e34df1c3cc0c49b2f0cc2b92de6a7b"
url: "https://github.com/lionelmennig/textfield_tags.git"
source: git
version: "3.0.1"
timezone:
dependency: "direct main"
description:

View File

@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 3.3.0+135
version: 3.3.0+136
environment:
sdk: ^3.7.2
@@ -78,9 +78,9 @@ dependencies:
image_picker_android: ^0.8.13+4
super_context_menu: ^0.9.1
modal_bottom_sheet: ^3.0.0
firebase_messaging: ^16.0.2
firebase_messaging: ^16.0.3
flutter_udid: ^4.0.0
firebase_core: ^4.1.1
firebase_core: ^4.2.0
web_socket_channel: ^3.0.3
material_symbols_icons: ^4.2874.0
drift: ^2.28.2
@@ -121,12 +121,12 @@ dependencies:
flutter_secure_storage: ^9.2.4
flutter_math_fork: ^0.7.4
share_plus: ^12.0.0
receive_sharing_intent: ^1.8.1
top_snackbar_flutter: ^3.3.0
textfield_tags:
# https://github.com/KasemJaffer/receive_sharing_intent/pull/333
receive_sharing_intent:
git:
url: https://github.com/lionelmennig/textfield_tags.git
ref: fixes/allow-controller-re-registration
url: https://github.com/KasemJaffer/receive_sharing_intent
ref: master
top_snackbar_flutter: ^3.3.0
mime: ^2.0.0
html2md: ^1.3.2
flutter_typeahead: ^5.2.0
@@ -134,11 +134,11 @@ dependencies:
flutter_app_update: ^3.2.2
archive: ^4.0.7
process_run: ^1.2.4
firebase_crashlytics: ^5.0.2
firebase_analytics: ^12.0.2
firebase_crashlytics: ^5.0.3
firebase_analytics: ^12.0.3
material_color_utilities: ^0.11.1
screenshot: ^3.0.0
flutter_card_swiper: ^7.0.2
flutter_card_swiper: ^7.1.0
file_saver: ^0.3.1
tray_manager: ^0.5.1
flutter_webrtc: ^1.2.0