mirror of
https://github.com/wgh136/pixes.git
synced 2025-09-27 04:57:23 +00:00
shortcuts
This commit is contained in:
@@ -148,7 +148,15 @@
|
||||
"Local": "本地",
|
||||
"Both": "同时",
|
||||
"This artwork is blocked": "此作品已被屏蔽",
|
||||
"Delete Invalid Items": "删除无效项目"
|
||||
"Delete Invalid Items": "删除无效项目",
|
||||
"Private Favorite": "私人收藏",
|
||||
"Shortcuts": "快捷键",
|
||||
"Page down": "向下翻页",
|
||||
"Page up": "向上翻页",
|
||||
"Next work": "下一作品",
|
||||
"Previous work": "上一作品",
|
||||
"Add to favorites": "添加收藏",
|
||||
"Follow the artist": "关注画师"
|
||||
},
|
||||
"zh_TW": {
|
||||
"Search": "搜索",
|
||||
@@ -299,6 +307,14 @@
|
||||
"Local": "本地",
|
||||
"Both": "同時",
|
||||
"This artwork is blocked": "此作品已被屏蔽",
|
||||
"Delete Invalid Items": "刪除無效項目"
|
||||
"Delete Invalid Items": "刪除無效項目",
|
||||
"Private Favorite": "私人收藏",
|
||||
"Shortcuts": "快捷鍵",
|
||||
"Page down": "向下翻頁",
|
||||
"Page up": "向上翻頁",
|
||||
"Next work": "下一作品",
|
||||
"Previous work": "上一作品",
|
||||
"Add to favorites": "添加收藏",
|
||||
"Follow the artist": "關注畫師"
|
||||
}
|
||||
}
|
@@ -24,6 +24,15 @@ class _Appdata {
|
||||
"readingLineHeight": 1.5,
|
||||
"readingParagraphSpacing": 8.0,
|
||||
"blockTags": [],
|
||||
"shortcuts": <int>[
|
||||
LogicalKeyboardKey.arrowDown.keyId,
|
||||
LogicalKeyboardKey.arrowUp.keyId,
|
||||
LogicalKeyboardKey.arrowRight.keyId,
|
||||
LogicalKeyboardKey.arrowLeft.keyId,
|
||||
LogicalKeyboardKey.enter.keyId,
|
||||
LogicalKeyboardKey.keyD.keyId,
|
||||
LogicalKeyboardKey.keyF.keyId,
|
||||
],
|
||||
};
|
||||
|
||||
bool lock = false;
|
||||
|
61
lib/components/keyboard.dart
Normal file
61
lib/components/keyboard.dart
Normal file
@@ -0,0 +1,61 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:pixes/foundation/app.dart';
|
||||
|
||||
typedef KeyEventHandler = void Function(LogicalKeyboardKey key);
|
||||
|
||||
class KeyEventListener extends StatefulWidget {
|
||||
const KeyEventListener({required this.child, super.key});
|
||||
|
||||
final Widget child;
|
||||
|
||||
static KeyEventListenerState? of(BuildContext context) {
|
||||
return context.findAncestorStateOfType<KeyEventListenerState>();
|
||||
}
|
||||
|
||||
@override
|
||||
State<KeyEventListener> createState() => KeyEventListenerState();
|
||||
}
|
||||
|
||||
class KeyEventListenerState extends State<KeyEventListener> {
|
||||
final focusNode = FocusNode();
|
||||
|
||||
final List<KeyEventHandler> _handlers = [];
|
||||
|
||||
void addHandler(KeyEventHandler handler) {
|
||||
_handlers.add(handler);
|
||||
}
|
||||
|
||||
void removeHandler(KeyEventHandler handler) {
|
||||
_handlers.remove(handler);
|
||||
}
|
||||
|
||||
void removeAll() {
|
||||
_handlers.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Focus(
|
||||
focusNode: focusNode,
|
||||
autofocus: true,
|
||||
onKeyEvent: (node, event) {
|
||||
if (event is! KeyUpEvent) return KeyEventResult.ignored;
|
||||
if (event.logicalKey == LogicalKeyboardKey.escape) {
|
||||
if (App.rootNavigatorKey.currentState?.canPop() ?? false) {
|
||||
App.rootNavigatorKey.currentState?.pop();
|
||||
}
|
||||
if (App.mainNavigatorKey?.currentState?.canPop() ?? false) {
|
||||
App.mainNavigatorKey?.currentState?.pop();
|
||||
}
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
for (var handler in _handlers) {
|
||||
handler(event.logicalKey);
|
||||
}
|
||||
return KeyEventResult.handled;
|
||||
},
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
}
|
@@ -6,6 +6,7 @@ import "package:flutter/material.dart" as md;
|
||||
import "package:flutter/services.dart";
|
||||
import "package:flutter_acrylic/flutter_acrylic.dart" as flutter_acrylic;
|
||||
import "package:pixes/appdata.dart";
|
||||
import "package:pixes/components/keyboard.dart";
|
||||
import "package:pixes/components/md.dart";
|
||||
import "package:pixes/components/message.dart";
|
||||
import "package:pixes/foundation/app.dart";
|
||||
@@ -88,7 +89,7 @@ class MyApp extends StatelessWidget {
|
||||
title: 'pixes',
|
||||
theme: FluentThemeData(
|
||||
brightness: brightness,
|
||||
fontFamily: App.isWindows ? 'font' : null,
|
||||
fontFamily: App.isWindows ? '微软雅黑' : null,
|
||||
accentColor: AccentColor.swatch({
|
||||
'darkest': darken(colorScheme.primary, 30),
|
||||
'darker': darken(colorScheme.primary, 20),
|
||||
@@ -97,7 +98,11 @@ class MyApp extends StatelessWidget {
|
||||
'light': lighten(colorScheme.primary, 10),
|
||||
'lighter': lighten(colorScheme.primary, 20),
|
||||
'lightest': lighten(colorScheme.primary, 30)
|
||||
})),
|
||||
}),
|
||||
focusTheme: const FocusThemeData(
|
||||
primaryBorder: BorderSide.none,
|
||||
secondaryBorder: BorderSide.none,
|
||||
)),
|
||||
home: const MainPage(),
|
||||
builder: (context, child) {
|
||||
ErrorWidget.builder = (details) {
|
||||
@@ -151,7 +156,7 @@ class MyApp extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
return widget;
|
||||
return KeyEventListener(child: widget);
|
||||
});
|
||||
},
|
||||
),
|
||||
|
@@ -7,6 +7,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||
import 'package:pixes/appdata.dart';
|
||||
import 'package:pixes/components/animated_image.dart';
|
||||
import 'package:pixes/components/keyboard.dart';
|
||||
import 'package:pixes/components/loading.dart';
|
||||
import 'package:pixes/components/message.dart';
|
||||
import 'package:pixes/components/page_route.dart';
|
||||
@@ -154,8 +155,15 @@ class IllustPage extends StatefulWidget {
|
||||
class _IllustPageState extends State<IllustPage> {
|
||||
String get id => "${widget.illust.author.id}#${widget.illust.id}";
|
||||
|
||||
final _bottomBarController = _BottomBarController();
|
||||
|
||||
KeyEventListenerState? keyboardListener;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
keyboardListener = KeyEventListener.of(context);
|
||||
keyboardListener?.removeAll();
|
||||
keyboardListener?.addHandler(handleKey);
|
||||
IllustPage.followCallbacks[id] = (v) {
|
||||
setState(() {
|
||||
widget.illust.author.isFollowed = v;
|
||||
@@ -166,6 +174,7 @@ class _IllustPageState extends State<IllustPage> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
keyboardListener?.removeHandler(handleKey);
|
||||
IllustPage.followCallbacks.remove(id);
|
||||
super.dispose();
|
||||
}
|
||||
@@ -173,7 +182,7 @@ class _IllustPageState extends State<IllustPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var isBlocked = checkIllusts([widget.illust]).isEmpty;
|
||||
return buildKeyboardListener(ColoredBox(
|
||||
return ColoredBox(
|
||||
color: FluentTheme.of(context).micaBackgroundColor,
|
||||
child: SizedBox.expand(
|
||||
child: ColoredBox(
|
||||
@@ -195,6 +204,7 @@ class _IllustPageState extends State<IllustPage> {
|
||||
constrains.maxHeight,
|
||||
constrains.maxWidth,
|
||||
updateCallback: () => setState(() {}),
|
||||
controller: _bottomBarController,
|
||||
),
|
||||
if (isBlocked)
|
||||
const Positioned.fill(
|
||||
@@ -209,36 +219,53 @@ class _IllustPageState extends State<IllustPage> {
|
||||
}),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
final scrollController = ScrollController();
|
||||
|
||||
Widget buildKeyboardListener(Widget child) {
|
||||
return KeyboardListener(
|
||||
focusNode: FocusNode(),
|
||||
autofocus: true,
|
||||
onKeyEvent: (event) {
|
||||
if (event is! KeyUpEvent) return;
|
||||
const kShortcutScrollOffset = 200;
|
||||
if (event.logicalKey == LogicalKeyboardKey.arrowDown) {
|
||||
void handleKey(LogicalKeyboardKey key) {
|
||||
const kShortcutScrollOffset = 200;
|
||||
|
||||
var shortcuts = appdata.settings["shortcuts"] as List;
|
||||
|
||||
switch (shortcuts.indexOf(key.keyId)) {
|
||||
case 0:
|
||||
if (scrollController.position.pixels >=
|
||||
scrollController.position.maxScrollExtent) {
|
||||
_bottomBarController.openOrClose();
|
||||
} else {
|
||||
scrollController.animateTo(
|
||||
scrollController.offset + kShortcutScrollOffset,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeOut);
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.arrowUp) {
|
||||
scrollController.animateTo(
|
||||
scrollController.offset - kShortcutScrollOffset,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeOut);
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.arrowRight) {
|
||||
widget.nextPage?.call();
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.arrowLeft) {
|
||||
widget.previousPage?.call();
|
||||
scrollController.offset + kShortcutScrollOffset,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: child,
|
||||
);
|
||||
break;
|
||||
case 1:
|
||||
if (_bottomBarController.isOpen()) {
|
||||
_bottomBarController.openOrClose();
|
||||
break;
|
||||
}
|
||||
scrollController.animateTo(
|
||||
scrollController.offset - kShortcutScrollOffset,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
widget.nextPage?.call();
|
||||
break;
|
||||
case 3:
|
||||
widget.previousPage?.call();
|
||||
break;
|
||||
case 4:
|
||||
_bottomBarController.favorite();
|
||||
case 5:
|
||||
_bottomBarController.download();
|
||||
case 6:
|
||||
_bottomBarController.follow();
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildBody(double width, double height) {
|
||||
@@ -344,8 +371,31 @@ class _IllustPageState extends State<IllustPage> {
|
||||
}
|
||||
}
|
||||
|
||||
class _BottomBarController {
|
||||
VoidCallback? _openOrClose;
|
||||
|
||||
VoidCallback get openOrClose => _openOrClose!;
|
||||
|
||||
bool Function()? _isOpen;
|
||||
|
||||
bool isOpen() => _isOpen!();
|
||||
|
||||
VoidCallback? _favorite;
|
||||
|
||||
VoidCallback get favorite => _favorite!;
|
||||
|
||||
VoidCallback? _download;
|
||||
|
||||
VoidCallback get download => _download!;
|
||||
|
||||
VoidCallback? _follow;
|
||||
|
||||
VoidCallback get follow => _follow!;
|
||||
}
|
||||
|
||||
class _BottomBar extends StatefulWidget {
|
||||
const _BottomBar(this.illust, this.height, this.width, {this.updateCallback});
|
||||
const _BottomBar(this.illust, this.height, this.width,
|
||||
{this.updateCallback, this.controller});
|
||||
|
||||
final void Function()? updateCallback;
|
||||
|
||||
@@ -355,6 +405,8 @@ class _BottomBar extends StatefulWidget {
|
||||
|
||||
final double width;
|
||||
|
||||
final _BottomBarController? controller;
|
||||
|
||||
@override
|
||||
State<_BottomBar> createState() => _BottomBarState();
|
||||
}
|
||||
@@ -391,9 +443,32 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin {
|
||||
..onCancel = _handlePointerCancel;
|
||||
animationController = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 180), value: 1);
|
||||
if (widget.controller != null) {
|
||||
widget.controller!._openOrClose = () {
|
||||
if (animationController.value == 0) {
|
||||
animationController.animateTo(1);
|
||||
} else if (animationController.value == 1) {
|
||||
animationController.animateTo(0);
|
||||
}
|
||||
};
|
||||
widget.controller!._isOpen = () => animationController.value == 0;
|
||||
widget.controller!._favorite = favorite;
|
||||
widget.controller!._download = () {
|
||||
DownloadManager().addDownloadingTask(widget.illust);
|
||||
setState(() {});
|
||||
};
|
||||
widget.controller!._follow = follow;
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
animationController.dispose();
|
||||
_recognizer.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _handlePointerDown(DragStartDetails details) {}
|
||||
void _handlePointerMove(DragUpdateDetails details) {
|
||||
var offset = details.primaryDelta ?? 0;
|
||||
@@ -541,31 +616,31 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin {
|
||||
|
||||
bool isFollowing = false;
|
||||
|
||||
Widget buildAuthor() {
|
||||
void follow() async {
|
||||
if (isFollowing) return;
|
||||
setState(() {
|
||||
isFollowing = true;
|
||||
});
|
||||
var method = widget.illust.author.isFollowed ? "delete" : "add";
|
||||
var res =
|
||||
await Network().follow(widget.illust.author.id.toString(), method);
|
||||
if (res.error) {
|
||||
if (mounted) {
|
||||
context.showToast(message: "Network Error");
|
||||
}
|
||||
} else {
|
||||
widget.illust.author.isFollowed = !widget.illust.author.isFollowed;
|
||||
void follow() async {
|
||||
if (isFollowing) return;
|
||||
setState(() {
|
||||
isFollowing = true;
|
||||
});
|
||||
var method = widget.illust.author.isFollowed ? "delete" : "add";
|
||||
var res =
|
||||
await Network().follow(widget.illust.author.id.toString(), method);
|
||||
if (res.error) {
|
||||
if (mounted) {
|
||||
context.showToast(message: "Network Error");
|
||||
}
|
||||
setState(() {
|
||||
isFollowing = false;
|
||||
});
|
||||
UserInfoPage.followCallbacks[widget.illust.author.id.toString()]
|
||||
?.call(widget.illust.author.isFollowed);
|
||||
UserPreviewWidget.followCallbacks[widget.illust.author.id.toString()]
|
||||
?.call(widget.illust.author.isFollowed);
|
||||
} else {
|
||||
widget.illust.author.isFollowed = !widget.illust.author.isFollowed;
|
||||
}
|
||||
setState(() {
|
||||
isFollowing = false;
|
||||
});
|
||||
UserInfoPage.followCallbacks[widget.illust.author.id.toString()]
|
||||
?.call(widget.illust.author.isFollowed);
|
||||
UserPreviewWidget.followCallbacks[widget.illust.author.id.toString()]
|
||||
?.call(widget.illust.author.isFollowed);
|
||||
}
|
||||
|
||||
Widget buildAuthor() {
|
||||
final bool showUserName = MediaQuery.of(context).size.width > 640;
|
||||
|
||||
return Card(
|
||||
@@ -981,7 +1056,7 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin {
|
||||
).fixWidth(96),
|
||||
Button(
|
||||
onPressed: () {
|
||||
var text = "https://www.pixiv.net/artworks/${widget.illust.id}";
|
||||
var text = "https://pixiv.net/artworks/${widget.illust.id}";
|
||||
Clipboard.setData(ClipboardData(text: text));
|
||||
showToast(context, message: "Copied".tl);
|
||||
},
|
||||
|
@@ -3,6 +3,7 @@ import "dart:async";
|
||||
import "package:fluent_ui/fluent_ui.dart";
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:pixes/appdata.dart";
|
||||
import "package:pixes/components/keyboard.dart";
|
||||
import "package:pixes/components/md.dart";
|
||||
import "package:pixes/foundation/app.dart";
|
||||
import "package:pixes/foundation/image_provider.dart";
|
||||
@@ -214,10 +215,10 @@ class _MainPageState extends State<MainPage> with WindowListener {
|
||||
context: context,
|
||||
removeTop: true,
|
||||
child: Navigator(
|
||||
key: navigatorKey,
|
||||
onGenerateRoute: (settings) => AppPageRoute(
|
||||
builder: (context) => const RecommendationPage()),
|
||||
),
|
||||
key: navigatorKey,
|
||||
onGenerateRoute: (settings) => AppPageRoute(
|
||||
builder: (context) => const RecommendationPage()),
|
||||
),
|
||||
))),
|
||||
);
|
||||
}
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:pixes/appdata.dart';
|
||||
import 'package:pixes/components/keyboard.dart';
|
||||
import 'package:pixes/components/md.dart';
|
||||
import 'package:pixes/components/message.dart';
|
||||
import 'package:pixes/components/page_route.dart';
|
||||
@@ -242,6 +244,14 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
context.to(() => const _BlockTagsPage());
|
||||
},
|
||||
)),
|
||||
buildItem(
|
||||
title: "Shortcuts".tl,
|
||||
action: Button(
|
||||
child: Text("Edit".tl).fixWidth(64),
|
||||
onPressed: () {
|
||||
context.to(() => const ShortcutsSettings());
|
||||
},
|
||||
)),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -538,3 +548,81 @@ class __BlockTagsPageState extends State<_BlockTagsPage> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ShortcutsSettings extends StatefulWidget {
|
||||
const ShortcutsSettings({super.key});
|
||||
|
||||
@override
|
||||
State<ShortcutsSettings> createState() => _ShortcutsSettingsState();
|
||||
}
|
||||
|
||||
class _ShortcutsSettingsState extends State<ShortcutsSettings> {
|
||||
int listening = -1;
|
||||
|
||||
KeyEventListenerState? listener;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
listener = KeyEventListener.of(context);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
listener?.removeAll();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
final settings = <String>[
|
||||
"Page down",
|
||||
"Page up",
|
||||
"Next work",
|
||||
"Previous work",
|
||||
"Add to favorites",
|
||||
"Download",
|
||||
"Follow the artist",
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(children: [
|
||||
TitleBar(title: "Shortcuts".tl),
|
||||
...settings.map((e) => buildItem(e, settings.indexOf(e)))
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildItem(String text, int index) {
|
||||
var keyText = listening == index
|
||||
? "Waiting..."
|
||||
: LogicalKeyboardKey(appdata.settings['shortcuts'][index]).keyLabel;
|
||||
return Card(
|
||||
padding: EdgeInsets.zero,
|
||||
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
|
||||
child: ListTile(
|
||||
title: Text(text.tl),
|
||||
trailing: Button(
|
||||
child: Text(keyText),
|
||||
onPressed: () {
|
||||
if (listening != -1) {
|
||||
listener?.removeAll();
|
||||
}
|
||||
setState(() {
|
||||
listening = index;
|
||||
});
|
||||
listener?.addHandler((key) {
|
||||
if (key == LogicalKeyboardKey.escape) return;
|
||||
setState(() {
|
||||
appdata.settings['shortcuts'][index] = key.keyId;
|
||||
listening = -1;
|
||||
appdata.writeData();
|
||||
});
|
||||
Future.microtask(() => listener?.removeAll());
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
56
pubspec.lock
56
pubspec.lock
@@ -73,6 +73,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
device_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: eead12d1a1ed83d8283ab4c2f3fca23ac4082f29f25f29dff0f758f57d06ec91
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.1.0"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
dio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -81,6 +97,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.4.3+1"
|
||||
dynamic_color:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dynamic_color
|
||||
sha256: eae98052fa6e2826bdac3dd2e921c6ce2903be15c6b7f8b6d8a5d49b5086298d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -190,6 +214,14 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_acrylic:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_acrylic
|
||||
sha256: a9a1fdf91ff1fb47858fd82507f57e255a132a5d355056694fdb9fd303633b18
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
flutter_file_dialog:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -293,6 +325,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
macos_window_utils:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: macos_window_utils
|
||||
sha256: "230be594d26f6dee92c5a1544f4242d25138a5bfb9f185b27f14de3949ef0be8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -515,22 +555,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
system_theme:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: system_theme
|
||||
sha256: "1f208db140a3d1e1eac2034b54920d95699c1534df576ced44b3312c5de3975f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
system_theme_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: system_theme_web
|
||||
sha256: "7566f5a928f6d28d7a60c97bea8a851d1c6bc9b86a4df2366230a97458489219"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.2"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
Reference in New Issue
Block a user