Compare commits

...

4 Commits

Author SHA1 Message Date
52f1826e91 🚀 Launch 2.2.2+62 2025-02-04 22:56:45 +08:00
28a4c86dbf Optimize post editor 2025-02-04 22:04:50 +08:00
85e48ce03b ♻️ Refactor tray with manager 2025-02-04 16:11:25 +08:00
efef61a8ea Tray icon basis 2025-02-04 15:43:20 +08:00
18 changed files with 273 additions and 121 deletions

BIN
assets/icon/tray-icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
assets/icon/tray-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

View File

@@ -609,5 +609,6 @@
"other": "{} Source Points" "other": "{} Source Points"
}, },
"aiThinkingProcess": "AI Thinking Process", "aiThinkingProcess": "AI Thinking Process",
"accountSettingsApplied": "Account settings have been applied." "accountSettingsApplied": "Account settings have been applied.",
"trayMenuExit": "Exit"
} }

View File

@@ -607,5 +607,6 @@
"other": "{} 源点" "other": "{} 源点"
}, },
"aiThinkingProcess": "AI 思考过程", "aiThinkingProcess": "AI 思考过程",
"accountSettingsApplied": "帐号设置已应用。" "accountSettingsApplied": "帐号设置已应用。",
"trayMenuExit": "退出"
} }

View File

@@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer'; import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'dart:ui';
import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:croppy/croppy.dart'; import 'package:croppy/croppy.dart';
@@ -10,6 +11,7 @@ import 'package:easy_localization_loader/easy_localization_loader.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
@@ -40,6 +42,7 @@ import 'package:surface/types/chat.dart';
import 'package:surface/types/realm.dart'; import 'package:surface/types/realm.dart';
import 'package:flutter_web_plugins/url_strategy.dart' show usePathUrlStrategy; import 'package:flutter_web_plugins/url_strategy.dart' show usePathUrlStrategy;
import 'package:surface/widgets/dialog.dart'; import 'package:surface/widgets/dialog.dart';
import 'package:tray_manager/tray_manager.dart';
import 'package:version/version.dart'; import 'package:version/version.dart';
import 'package:workmanager/workmanager.dart'; import 'package:workmanager/workmanager.dart';
import 'package:in_app_review/in_app_review.dart'; import 'package:in_app_review/in_app_review.dart';
@@ -206,7 +209,7 @@ class _AppSplashScreen extends StatefulWidget {
State<_AppSplashScreen> createState() => _AppSplashScreenState(); State<_AppSplashScreen> createState() => _AppSplashScreenState();
} }
class _AppSplashScreenState extends State<_AppSplashScreen> { class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
void _tryRequestRating() async { void _tryRequestRating() async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
if (prefs.containsKey('first_boot_time')) { if (prefs.containsKey('first_boot_time')) {
@@ -294,9 +297,45 @@ class _AppSplashScreenState extends State<_AppSplashScreen> {
await widgetUpdateRandomPost(); await widgetUpdateRandomPost();
} }
Future<void> _trayInitialization() async {
if (kIsWeb || Platform.isAndroid || Platform.isIOS) return;
final icon = Platform.isWindows ? 'assets/icon/tray-icon.ico' : 'assets/icon/tray-icon.png';
final appVersion = await PackageInfo.fromPlatform();
trayManager.addListener(this);
await trayManager.setIcon(icon);
Menu menu = Menu(
items: [
MenuItem(
key: 'version_label',
label: 'Solian ${appVersion.version}+${appVersion.buildNumber}',
disabled: true,
),
MenuItem.separator(),
MenuItem(
key: 'exit',
label: 'trayMenuExit'.tr(),
),
],
);
await trayManager.setContextMenu(menu);
}
AppLifecycleListener? _appLifecycleListener;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
if (!kIsWeb && !(Platform.isIOS || Platform.isAndroid)) {
_appLifecycleListener = AppLifecycleListener(
onExitRequested: _onExitRequested,
);
}
_trayInitialization();
_initialize().then((_) { _initialize().then((_) {
_postInitialization(); _postInitialization();
_tryRequestRating(); _tryRequestRating();
@@ -304,6 +343,45 @@ class _AppSplashScreenState extends State<_AppSplashScreen> {
}); });
} }
Future<AppExitResponse> _onExitRequested() async {
appWindow.hide();
return AppExitResponse.cancel;
}
@override
void onTrayIconMouseDown() {
if (Platform.isWindows) {
appWindow.show();
} else {
trayManager.popUpContextMenu();
}
}
@override
void onTrayIconRightMouseDown() {
if (Platform.isWindows) {
trayManager.popUpContextMenu();
} else {
appWindow.show();
}
}
@override
void onTrayMenuItemClick(MenuItem menuItem) {
switch (menuItem.key) {
case 'exit':
_appLifecycleListener?.dispose();
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
break;
}
}
@override
void dispose() {
if (!kIsWeb && !(Platform.isAndroid || Platform.isIOS)) trayManager.removeListener(this);
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final cfg = context.read<ConfigProvider>(); final cfg = context.read<ConfigProvider>();

View File

@@ -12,6 +12,7 @@ import 'package:surface/providers/sn_network.dart';
import 'package:surface/providers/userinfo.dart'; import 'package:surface/providers/userinfo.dart';
import 'package:surface/providers/websocket.dart'; import 'package:surface/providers/websocket.dart';
import 'package:surface/types/notification.dart'; import 'package:surface/types/notification.dart';
import 'package:tray_manager/tray_manager.dart';
class NotificationProvider extends ChangeNotifier { class NotificationProvider extends ChangeNotifier {
late final SnNetworkProvider _sn; late final SnNetworkProvider _sn;
@@ -86,14 +87,26 @@ class NotificationProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
}); });
notifyListeners(); notifyListeners();
updateTray();
final doHaptic = _cfg.prefs.getBool(kAppNotifyWithHaptic) ?? true; final doHaptic = _cfg.prefs.getBool(kAppNotifyWithHaptic) ?? true;
if (doHaptic) HapticFeedback.mediumImpact(); if (doHaptic) HapticFeedback.mediumImpact();
} }
}); });
} }
void updateTray() {
if (kIsWeb || Platform.isAndroid || Platform.isIOS) return;
if (notifications.isEmpty) {
trayManager.setTitle('');
} else {
trayManager.setTitle(' ${notifications.length.toString()}');
}
}
void clear() { void clear() {
showingCount = 0; showingCount = 0;
notifications.clear();
updateTray();
notifyListeners(); notifyListeners();
} }
} }

View File

@@ -47,6 +47,7 @@ class HomeWidgetProvider {
} }
Future<void> widgetUpdateRandomPost() async { Future<void> widgetUpdateRandomPost() async {
if (kIsWeb || (!Platform.isAndroid && !Platform.isIOS)) return;
final snc = await SnNetworkProvider.createOffContextClient(); final snc = await SnNetworkProvider.createOffContextClient();
final resp = await snc.get('/cgi/co/recommendations/shuffle?take=1'); final resp = await snc.get('/cgi/co/recommendations/shuffle?take=1');
final post = SnPost.fromJson(resp.data['data'][0]); final post = SnPost.fromJson(resp.data['data'][0]);

View File

@@ -7,6 +7,7 @@ import 'package:material_symbols_icons/symbols.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:relative_time/relative_time.dart'; import 'package:relative_time/relative_time.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'package:surface/providers/notification.dart';
import 'package:surface/providers/sn_network.dart'; import 'package:surface/providers/sn_network.dart';
import 'package:surface/types/notification.dart'; import 'package:surface/types/notification.dart';
import 'package:surface/types/post.dart'; import 'package:surface/types/post.dart';
@@ -54,6 +55,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
try { try {
final sn = context.read<SnNetworkProvider>(); final sn = context.read<SnNetworkProvider>();
final nty = context.read<NotificationProvider>();
final resp = await sn.client.get('/cgi/id/notifications?take=10'); final resp = await sn.client.get('/cgi/id/notifications?take=10');
_totalCount = resp.data['count']; _totalCount = resp.data['count'];
_notifications.addAll( _notifications.addAll(
@@ -62,6 +64,7 @@ class _NotificationScreenState extends State<NotificationScreen> {
.cast<SnNotification>() ?? .cast<SnNotification>() ??
[], [],
); );
nty.updateTray();
} catch (err) { } catch (err) {
if (!mounted) return; if (!mounted) return;
context.showErrorDialog(err); context.showErrorDialog(err);
@@ -88,9 +91,11 @@ class _NotificationScreenState extends State<NotificationScreen> {
try { try {
final sn = context.read<SnNetworkProvider>(); final sn = context.read<SnNetworkProvider>();
final nty = context.read<NotificationProvider>();
final resp = await sn.client.put('/cgi/id/notifications/read/all'); final resp = await sn.client.put('/cgi/id/notifications/read/all');
_notifications.clear(); _notifications.clear();
_fetchNotifications(); _fetchNotifications();
nty.clear();
if (!mounted) return; if (!mounted) return;
context.showSnackbar( context.showSnackbar(

View File

@@ -153,6 +153,7 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
), ),
), ),
]), ]),
maxLines: 2,
), ),
actions: [ actions: [
IconButton( IconButton(
@@ -250,121 +251,130 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
), ),
const Divider(height: 1), const Divider(height: 1),
Expanded( Expanded(
child: SingleChildScrollView( child: Stack(
padding: EdgeInsets.only(bottom: 8), children: [
child: Column( SingleChildScrollView(
children: [ padding: EdgeInsets.only(bottom: 160),
// Replying Notice child: Column(
if (_writeController.replyingPost != null) children: [
Column( // Replying Notice
children: [ if (_writeController.replyingPost != null)
ExpansionTile( Column(
minTileHeight: 48, children: [
leading: const Icon(Symbols.reply).padding(left: 4), ExpansionTile(
title: Text('postReplyingNotice') minTileHeight: 48,
.fontSize(15) leading: const Icon(Symbols.reply).padding(left: 4),
.tr(args: ['@${_writeController.replyingPost!.publisher.name}']), title: Text('postReplyingNotice')
children: <Widget>[PostItem(data: _writeController.replyingPost!)], .fontSize(15)
), .tr(args: ['@${_writeController.replyingPost!.publisher.name}']),
const Divider(height: 1), children: <Widget>[PostItem(data: _writeController.replyingPost!)],
], ),
), const Divider(height: 1),
// Reposting Notice
if (_writeController.repostingPost != null)
Column(
children: [
ExpansionTile(
minTileHeight: 48,
leading: const Icon(Symbols.forward).padding(left: 4),
title: Text('postRepostingNotice')
.fontSize(15)
.tr(args: ['@${_writeController.repostingPost!.publisher.name}']),
children: <Widget>[
PostItem(
data: _writeController.repostingPost!,
)
], ],
), ),
const Divider(height: 1), // Reposting Notice
], if (_writeController.repostingPost != null)
), Column(
// Editing Notice children: [
if (_writeController.editingPost != null) ExpansionTile(
Column( minTileHeight: 48,
children: [ leading: const Icon(Symbols.forward).padding(left: 4),
ExpansionTile( title: Text('postRepostingNotice')
minTileHeight: 48, .fontSize(15)
leading: const Icon(Symbols.edit_note).padding(left: 4), .tr(args: ['@${_writeController.repostingPost!.publisher.name}']),
title: Text('postEditingNotice') children: <Widget>[
.fontSize(15) PostItem(
.tr(args: ['@${_writeController.editingPost!.publisher.name}']), data: _writeController.repostingPost!,
children: <Widget>[PostItem(data: _writeController.editingPost!)], )
],
),
const Divider(height: 1),
],
), ),
const Divider(height: 1), // Editing Notice
], if (_writeController.editingPost != null)
), Column(
// Content Input Area children: [
Container( ExpansionTile(
constraints: const BoxConstraints(maxWidth: 640), minTileHeight: 48,
child: TextField( leading: const Icon(Symbols.edit_note).padding(left: 4),
controller: _writeController.contentController, title: Text('postEditingNotice')
maxLines: null, .fontSize(15)
decoration: InputDecoration( .tr(args: ['@${_writeController.editingPost!.publisher.name}']),
hintText: 'fieldPostContent'.tr(), children: <Widget>[PostItem(data: _writeController.editingPost!)],
hintStyle: TextStyle(fontSize: 14), ),
isCollapsed: true, const Divider(height: 1),
contentPadding: const EdgeInsets.symmetric( ],
horizontal: 16, ),
// Content Input Area
Container(
constraints: const BoxConstraints(maxWidth: 640),
child: TextField(
controller: _writeController.contentController,
maxLines: null,
decoration: InputDecoration(
hintText: 'fieldPostContent'.tr(),
hintStyle: TextStyle(fontSize: 14),
isCollapsed: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
),
border: InputBorder.none,
),
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
), ),
border: InputBorder.none,
), ),
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), ]
), .expandIndexed(
(idx, ele) => [
if (idx != 0 || _writeController.isRelatedNull) const Gap(8),
ele,
],
)
.toList(),
), ),
] ),
.expandIndexed( if (_writeController.attachments.isNotEmpty || _writeController.thumbnail != null)
(idx, ele) => [ Positioned(
if (idx != 0 || _writeController.isRelatedNull) const Gap(8), bottom: 0,
ele, left: 0,
], right: 0,
) child: PostMediaPendingList(
.toList(), thumbnail: _writeController.thumbnail,
), attachments: _writeController.attachments,
isBusy: _writeController.isBusy,
onUpload: (int idx) async {
await _writeController.uploadSingleAttachment(context, idx);
},
onPostSetThumbnail: (int? idx) {
_writeController.setThumbnail(idx);
},
onInsertLink: (int idx) async {
_writeController.contentController.text +=
'\n![](solink://attachments/${_writeController.attachments[idx].attachment!.rid})';
},
onUpdate: (int idx, PostWriteMedia updatedMedia) async {
_writeController.setIsBusy(true);
try {
_writeController.setAttachmentAt(idx, updatedMedia);
} finally {
_writeController.setIsBusy(false);
}
},
onRemove: (int idx) async {
_writeController.setIsBusy(true);
try {
_writeController.removeAttachmentAt(idx);
} finally {
_writeController.setIsBusy(false);
}
},
onUpdateBusy: (state) => _writeController.setIsBusy(state),
).padding(bottom: 8),
),
],
), ),
), ),
if (_writeController.attachments.isNotEmpty || _writeController.thumbnail != null)
PostMediaPendingList(
thumbnail: _writeController.thumbnail,
attachments: _writeController.attachments,
isBusy: _writeController.isBusy,
onUpload: (int idx) async {
await _writeController.uploadSingleAttachment(context, idx);
},
onPostSetThumbnail: (int? idx) {
_writeController.setThumbnail(idx);
},
onInsertLink: (int idx) async {
_writeController.contentController.text +=
'\n![](solink://attachments/${_writeController.attachments[idx].attachment!.rid})';
},
onUpdate: (int idx, PostWriteMedia updatedMedia) async {
_writeController.setIsBusy(true);
try {
_writeController.setAttachmentAt(idx, updatedMedia);
} finally {
_writeController.setIsBusy(false);
}
},
onRemove: (int idx) async {
_writeController.setIsBusy(true);
try {
_writeController.removeAttachmentAt(idx);
} finally {
_writeController.setIsBusy(false);
}
},
onUpdateBusy: (state) => _writeController.setIsBusy(state),
).padding(bottom: 8),
Material( Material(
elevation: 2, elevation: 2,
child: Column( child: Column(

View File

@@ -154,7 +154,6 @@ class ChatMessageInputState extends State<ChatMessageInput> {
void _showEmojiPicker(BuildContext context) { void _showEmojiPicker(BuildContext context) {
final overlay = Overlay.of(context); final overlay = Overlay.of(context);
final sticker = context.read<SnStickerProvider>();
_overlayEntry = OverlayEntry( _overlayEntry = OverlayEntry(
builder: (context) => Positioned( builder: (context) => Positioned(
bottom: 16 + MediaQuery.of(context).padding.bottom, bottom: 16 + MediaQuery.of(context).padding.bottom,
@@ -363,7 +362,7 @@ class _StickerPicker extends StatelessWidget {
final Function? onDismiss; final Function? onDismiss;
final Function(String)? onInsert; final Function(String)? onInsert;
const _StickerPicker({super.key, this.onDismiss, required this.originalText, this.onInsert}); const _StickerPicker({this.onDismiss, required this.originalText, this.onInsert});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@@ -14,6 +14,7 @@
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h> #include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
#include <media_kit_video/media_kit_video_plugin.h> #include <media_kit_video/media_kit_video_plugin.h>
#include <pasteboard/pasteboard_plugin.h> #include <pasteboard/pasteboard_plugin.h>
#include <tray_manager/tray_manager_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
@@ -41,6 +42,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) pasteboard_registrar = g_autoptr(FlPluginRegistrar) pasteboard_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin");
pasteboard_plugin_register_with_registrar(pasteboard_registrar); pasteboard_plugin_register_with_registrar(pasteboard_registrar);
g_autoptr(FlPluginRegistrar) tray_manager_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "TrayManagerPlugin");
tray_manager_plugin_register_with_registrar(tray_manager_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View File

@@ -11,6 +11,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
media_kit_libs_linux media_kit_libs_linux
media_kit_video media_kit_video
pasteboard pasteboard
tray_manager
url_launcher_linux url_launcher_linux
) )

View File

@@ -29,6 +29,7 @@ import screen_brightness_macos
import share_plus import share_plus
import shared_preferences_foundation import shared_preferences_foundation
import sqflite_darwin import sqflite_darwin
import tray_manager
import url_launcher_macos import url_launcher_macos
import video_compress import video_compress
import wakelock_plus import wakelock_plus
@@ -58,6 +59,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
VideoCompressPlugin.register(with: registry.registrar(forPlugin: "VideoCompressPlugin")) VideoCompressPlugin.register(with: registry.registrar(forPlugin: "VideoCompressPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))

View File

@@ -174,6 +174,8 @@ PODS:
- sqflite_darwin (0.0.4): - sqflite_darwin (0.0.4):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- tray_manager (0.0.1):
- FlutterMacOS
- url_launcher_macos (0.0.1): - url_launcher_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
- video_compress (0.3.0): - video_compress (0.3.0):
@@ -210,6 +212,7 @@ DEPENDENCIES:
- share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`) - sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`)
- tray_manager (from `Flutter/ephemeral/.symlinks/plugins/tray_manager/macos`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- video_compress (from `Flutter/ephemeral/.symlinks/plugins/video_compress/macos`) - video_compress (from `Flutter/ephemeral/.symlinks/plugins/video_compress/macos`)
- wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`) - wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`)
@@ -286,6 +289,8 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sqflite_darwin: sqflite_darwin:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin :path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin
tray_manager:
:path: Flutter/ephemeral/.symlinks/plugins/tray_manager/macos
url_launcher_macos: url_launcher_macos:
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
video_compress: video_compress:
@@ -334,6 +339,7 @@ SPEC CHECKSUMS:
share_plus: 1fa619de8392a4398bfaf176d441853922614e89 share_plus: 1fa619de8392a4398bfaf176d441853922614e89
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
tray_manager: 9064e219c56d75c476e46b9a21182087930baf90
url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404 url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
video_compress: c896234f100791b5fef7f049afa38f6d2ef7b42f video_compress: c896234f100791b5fef7f049afa38f6d2ef7b42f
wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269 wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269

View File

@@ -764,10 +764,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_markdown name: flutter_markdown
sha256: e37f4c69a07b07bb92622ef6b131a53c9aae48f64b176340af9e8e5238718487 sha256: "46cdcdcd216f15ac04c80e24e814a89ea7143654442c53ba67fec349b4d44565"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.5" version: "0.7.6"
flutter_native_splash: flutter_native_splash:
dependency: "direct dev" dependency: "direct dev"
description: description:
@@ -1282,6 +1282,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.5" version: "1.2.5"
menu_base:
dependency: transitive
description:
name: menu_base
sha256: "820368014a171bd1241030278e6c2617354f492f5c703d7b7d4570a6b8b84405"
url: "https://pub.dev"
source: hosted
version: "0.1.1"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@@ -1334,18 +1342,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: package_info_plus name: package_info_plus
sha256: b15fad91c4d3d1f2b48c053dd41cb82da007c27407dc9ab5f9aa59881d0e39d4 sha256: c447a3c3e7be4addf129b8f9ab6a4bd5d166b78918223e223b61fddf4d07e254
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.1.4" version: "8.2.0"
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: a5ef9986efc7bf772f2696183a3992615baa76c1ffb1189318dd8803778fb05b sha256: "205ec83335c2ab9107bbba3f8997f9356d72ca3c715d2f038fc773d0366b4c76"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.1.0"
pasteboard: pasteboard:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -1778,6 +1786,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.1" version: "2.0.1"
shortid:
dependency: transitive
description:
name: shortid
sha256: d0b40e3dbb50497dad107e19c54ca7de0d1a274eb9b4404991e443dadb9ebedb
url: "https://pub.dev"
source: hosted
version: "0.1.2"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@@ -1951,6 +1967,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
tray_manager:
dependency: "direct main"
description:
name: tray_manager
sha256: "80be6c508159a6f3c57983de795209ac13453e9832fd574143b06dceee188ed2"
url: "https://pub.dev"
source: hosted
version: "0.3.2"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@@ -2059,10 +2083,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vector_graphics name: vector_graphics
sha256: "7ed22c21d7fdcc88dd6ba7860384af438cd220b251ad65dfc142ab722fabef61" sha256: a1870d398158844fe5db12441611ed9a2222ff4340258b539eaf3590c1b4bd7e
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.16" version: "1.1.17"
vector_graphics_codec: vector_graphics_codec:
dependency: transitive dependency: transitive
description: 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 # 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 # 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. # of the product and file versions while build-number is used as the build suffix.
version: 2.2.2+61 version: 2.2.2+62
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4
@@ -118,6 +118,7 @@ dependencies:
flutter_inappwebview: ^6.1.5 flutter_inappwebview: ^6.1.5
html: ^0.15.5 html: ^0.15.5
xml: ^6.5.0 xml: ^6.5.0
tray_manager: ^0.3.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@@ -152,6 +153,8 @@ flutter:
- assets/icon/icon.png - assets/icon/icon.png
- assets/icon/icon-dark.png - assets/icon/icon-dark.png
- assets/icon/icon-light-radius.png - assets/icon/icon-light-radius.png
- assets/icon/tray-icon.ico
- assets/icon/tray-icon.png
- assets/translations/ - assets/translations/
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see

View File

@@ -22,6 +22,7 @@
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <screen_brightness_windows/screen_brightness_windows_plugin.h> #include <screen_brightness_windows/screen_brightness_windows_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h> #include <share_plus/share_plus_windows_plugin_c_api.h>
#include <tray_manager/tray_manager_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
@@ -57,6 +58,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("ScreenBrightnessWindowsPlugin")); registry->GetRegistrarForPlugin("ScreenBrightnessWindowsPlugin"));
SharePlusWindowsPluginCApiRegisterWithRegistrar( SharePlusWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
TrayManagerPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("TrayManagerPlugin"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows")); registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View File

@@ -19,6 +19,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
permission_handler_windows permission_handler_windows
screen_brightness_windows screen_brightness_windows
share_plus share_plus
tray_manager
url_launcher_windows url_launcher_windows
) )