Merge remote-tracking branch 'origin/linux-window' into v1.3.4-dev

# Conflicts:
#	assets/translation.json
This commit is contained in:
2025-03-27 13:13:18 +08:00
7 changed files with 85 additions and 62 deletions

View File

@@ -26,6 +26,9 @@ jobs:
echo "$CERTIFICATE" | base64 --decode > signing_certificate.p12 echo "$CERTIFICATE" | base64 --decode > signing_certificate.p12
security import signing_certificate.p12 -k ~/Library/Keychains/login.keychain -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign security import signing_certificate.p12 -k ~/Library/Keychains/login.keychain -P "$CERTIFICATE_PASSWORD" -T /usr/bin/codesign
- name: Check rust-toolchain.toml
run: rustup show
# Step 2: Build the Flutter macOS app # Step 2: Build the Flutter macOS app
- name: Build Flutter macOS App - name: Build Flutter macOS App
run: flutter build macos --release run: flutter build macos --release
@@ -97,10 +100,8 @@ jobs:
with: with:
distribution: 'oracle' distribution: 'oracle'
java-version: '17' java-version: '17'
- name: Setup Rust - name: Check rust-toolchain.toml
run: | run: rustup show
rustup update
rustup default stable
- run: flutter pub get - run: flutter pub get
- run: flutter build apk --release - run: flutter build apk --release
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4

View File

@@ -358,7 +358,7 @@
"Once the operation is successful, app will automatically sync data with the server.": "操作成功后, APP将自动与服务器同步数据", "Once the operation is successful, app will automatically sync data with the server.": "操作成功后, APP将自动与服务器同步数据",
"Cache cleared": "缓存已清除", "Cache cleared": "缓存已清除",
"Disabled": "已禁用", "Disabled": "已禁用",
"WebDAV Auto Sync": "WebDAV 自动同步", "Auto Sync Data": "自动同步数据",
"Mark all as read": "全部标记为已读", "Mark all as read": "全部标记为已读",
"Do you want to mark all as read?" : "您要全部标记为已读吗?", "Do you want to mark all as read?" : "您要全部标记为已读吗?",
"Swipe down for previous chapter": "向下滑动查看上一章", "Swipe down for previous chapter": "向下滑动查看上一章",
@@ -377,7 +377,8 @@
"Jump to page": "跳转到页面", "Jump to page": "跳转到页面",
"Page": "页面", "Page": "页面",
"Jump": "跳转", "Jump": "跳转",
"Copy Image": "复制图片" "Copy Image": "复制图片",
"A valid WebDav directory URL": "有效的WebDav目录URL"
}, },
"zh_TW": { "zh_TW": {
"Home": "首頁", "Home": "首頁",
@@ -738,7 +739,7 @@
"Once the operation is successful, app will automatically sync data with the server.": "操作成功後, APP將自動與伺服器同步資料", "Once the operation is successful, app will automatically sync data with the server.": "操作成功後, APP將自動與伺服器同步資料",
"Cache cleared": "快取已清除", "Cache cleared": "快取已清除",
"Disabled": "已停用", "Disabled": "已停用",
"WebDAV Auto Sync": "WebDAV 自動同步", "Auto Sync Data": "自動同步資料",
"Mark all as read": "全部標記為已讀", "Mark all as read": "全部標記為已讀",
"Do you want to mark all as read?" : "您要全部標記為已讀嗎?", "Do you want to mark all as read?" : "您要全部標記為已讀嗎?",
"Swipe down for previous chapter": "向下滑動查看上一章", "Swipe down for previous chapter": "向下滑動查看上一章",
@@ -757,6 +758,7 @@
"Jump to page": "跳轉到頁面", "Jump to page": "跳轉到頁面",
"Page": "頁面", "Page": "頁面",
"Jump": "跳轉", "Jump": "跳轉",
"Copy Image": "複製圖片" "Copy Image": "複製圖片",
"A valid WebDav directory URL": "有效的WebDav目錄URL"
} }
} }

View File

@@ -150,9 +150,10 @@ class _WindowFrameState extends State<WindowFrame> {
onPressed: debug, onPressed: debug,
child: Text('Debug'), child: Text('Debug'),
), ),
if (!App.isMacOS) _WindowButtons( if (!App.isMacOS)
onClose: _onClose, _WindowButtons(
) onClose: _onClose,
)
], ],
), ),
); );
@@ -562,31 +563,31 @@ class _VirtualWindowFrameState extends State<VirtualWindowFrame>
} }
Widget _buildVirtualWindowFrame(BuildContext context) { Widget _buildVirtualWindowFrame(BuildContext context) {
return DecoratedBox( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.transparent, borderRadius: BorderRadius.circular(_isMaximized ? 0 : 8),
border: Border.all( color: Colors.transparent,
color: Theme.of(context).dividerColor, boxShadow: <BoxShadow>[
width: (_isMaximized || _isFullScreen) ? 0 : 1,
),
boxShadow: <BoxShadow>[
if (!_isMaximized && !_isFullScreen)
BoxShadow( BoxShadow(
color: Colors.black.toOpacity(0.1), color: Colors.black.toOpacity(_isFocused ? 0.4 : 0.2),
offset: Offset(0.0, _isFocused ? 4 : 2), offset: Offset(0.0, 2),
blurRadius: 6, blurRadius: 4,
) )
], ],
), ),
child: widget.child, clipBehavior: Clip.antiAlias,
); child: widget.child,
);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DragToResizeArea( return DragToResizeArea(
enableResizeEdges: (_isMaximized || _isFullScreen) ? [] : null, enableResizeEdges: (_isMaximized || _isFullScreen) ? [] : null,
child: _buildVirtualWindowFrame(context), child: Padding(
padding: EdgeInsets.all(_isMaximized ? 0 : 4),
child: _buildVirtualWindowFrame(context),
),
); );
} }

View File

@@ -34,13 +34,10 @@ void main(List<String> args) {
await windowManager.setBackgroundColor(Colors.transparent); await windowManager.setBackgroundColor(Colors.transparent);
} }
await windowManager.setMinimumSize(const Size(500, 600)); await windowManager.setMinimumSize(const Size(500, 600));
if (!App.isLinux) { var placement = await WindowPlacement.loadFromFile();
// https://github.com/leanflutter/window_manager/issues/460 await placement.applyToWindow();
var placement = await WindowPlacement.loadFromFile(); await windowManager.show();
await placement.applyToWindow(); WindowPlacement.loop();
await windowManager.show();
WindowPlacement.loop();
}
}); });
} }
}, (error, stack) { }, (error, stack) {
@@ -201,6 +198,7 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
'dark' => ThemeMode.dark, 'dark' => ThemeMode.dark,
_ => ThemeMode.system _ => ThemeMode.system
}, },
color: Colors.transparent,
localizationsDelegates: [ localizationsDelegates: [
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
@@ -248,6 +246,7 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
); );
} }
return _SystemUiProvider(Material( return _SystemUiProvider(Material(
color: App.isLinux ? Colors.transparent : null,
child: widget, child: widget,
)); ));
} }

View File

@@ -330,11 +330,10 @@ class _WebdavSettingState extends State<_WebdavSetting> {
String url = ""; String url = "";
String user = ""; String user = "";
String pass = ""; String pass = "";
bool autoSync = false; bool autoSync = true;
bool isTesting = false; bool isTesting = false;
bool upload = true; bool upload = true;
bool isEnabled = false;
@override @override
void initState() { void initState() {
@@ -349,8 +348,7 @@ class _WebdavSettingState extends State<_WebdavSetting> {
url = configs[0]; url = configs[0];
user = configs[1]; user = configs[1];
pass = configs[2]; pass = configs[2];
isEnabled = true; autoSync = appdata.implicitData['webdavAutoSync'] ?? true;
autoSync = appdata.implicitData['webdavAutoSync'] ?? false;
} }
void onAutoSyncChanged(bool value) { void onAutoSyncChanged(bool value) {
@@ -368,16 +366,11 @@ class _WebdavSettingState extends State<_WebdavSetting> {
body: SingleChildScrollView( body: SingleChildScrollView(
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 12),
SwitchListTile(
title: Text("WebDAV Auto Sync".tl),
value: autoSync,
onChanged: onAutoSyncChanged,
),
const SizedBox(height: 12), const SizedBox(height: 12),
TextField( TextField(
decoration: const InputDecoration( decoration: InputDecoration(
labelText: "URL", labelText: "URL",
hintText: "A valid WebDav directory URL".tl,
border: OutlineInputBorder(), border: OutlineInputBorder(),
), ),
controller: TextEditingController(text: url), controller: TextEditingController(text: url),
@@ -402,6 +395,16 @@ class _WebdavSettingState extends State<_WebdavSetting> {
onChanged: (value) => pass = value, onChanged: (value) => pass = value,
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
ListTile(
leading: Icon(Icons.sync),
title: Text("Auto Sync Data".tl),
contentPadding: EdgeInsets.zero,
trailing: Switch(
value: autoSync,
onChanged: onAutoSyncChanged,
),
),
const SizedBox(height: 12),
Row( Row(
children: [ children: [
Text("Operation".tl), Text("Operation".tl),
@@ -428,21 +431,28 @@ class _WebdavSettingState extends State<_WebdavSetting> {
], ],
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Container( AnimatedSize(
padding: const EdgeInsets.all(8), duration: const Duration(milliseconds: 200),
decoration: BoxDecoration( child: autoSync
color: Theme.of(context).colorScheme.primaryContainer, ? Container(
borderRadius: BorderRadius.circular(8), padding: const EdgeInsets.all(8),
), decoration: BoxDecoration(
child: Row( color: Theme.of(context).colorScheme.primaryContainer,
children: [ borderRadius: BorderRadius.circular(8),
const Icon(Icons.info_outline, size: 20), ),
const SizedBox(width: 8), child: Row(
Expanded( children: [
child: Text("Once the operation is successful, app will automatically sync data with the server.".tl), const Icon(Icons.info_outline, size: 20),
), const SizedBox(width: 8),
], Expanded(
), child: Text(
"Once the operation is successful, app will automatically sync data with the server."
.tl),
),
],
),
)
: const SizedBox.shrink(),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Center( Center(

View File

@@ -48,6 +48,12 @@ static void my_application_activate(GApplication* application) {
} }
gtk_window_set_default_size(window, 1280, 720); gtk_window_set_default_size(window, 1280, 720);
GdkVisual* visual;
gtk_widget_set_app_paintable(GTK_WIDGET(window), TRUE);
visual = gdk_screen_get_rgba_visual(screen);
if (visual != NULL && gdk_screen_is_composited(screen)) {
gtk_widget_set_visual(GTK_WIDGET(window), visual);
}
gtk_widget_show(GTK_WIDGET(window)); gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new(); g_autoptr(FlDartProject) project = fl_dart_project_new();
@@ -58,6 +64,7 @@ static void my_application_activate(GApplication* application) {
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
fl_register_plugins(FL_PLUGIN_REGISTRY(view)); fl_register_plugins(FL_PLUGIN_REGISTRY(view));
gtk_widget_hide(GTK_WIDGET(window));
gtk_widget_grab_focus(GTK_WIDGET(view)); gtk_widget_grab_focus(GTK_WIDGET(view));
} }

3
rust-toolchain.toml Normal file
View File

@@ -0,0 +1,3 @@
[toolchain]
channel = "1.85.1"
targets = ["aarch64-apple-darwin", "x86_64-apple-darwin", "aarch64-linux-android", "armv7-linux-androideabi", "x86_64-linux-android"]