Skip to content

Commit

Permalink
标签页右键菜单
Browse files Browse the repository at this point in the history
  • Loading branch information
lyming99 committed Feb 27, 2024
1 parent f62986a commit 9b03703
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 32 deletions.
13 changes: 8 additions & 5 deletions lib/app/windows/controller/home/win_home_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'dart:io';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:super_drag_and_drop/super_drag_and_drop.dart';
import 'package:uuid/uuid.dart';
import 'package:wenznote/app/mobile/controller/settings/mobile_settings_controller.dart';
import 'package:wenznote/app/mobile/view/settings/mobile_settings_page.dart';
import 'package:wenznote/app/windows/controller/card/win_card_set_controller.dart';
Expand All @@ -14,12 +16,11 @@ import 'package:wenznote/app/windows/widgets/win_tab_view.dart';
import 'package:wenznote/commons/mvc/controller.dart';
import 'package:wenznote/commons/util/markdown/markdown.dart';
import 'package:wenznote/editor/crdt/doc_utils.dart';
import 'package:wenznote/editor/widget/drop_menu.dart';
import 'package:wenznote/model/note/enum/note_type.dart';
import 'package:wenznote/model/note/po/doc_po.dart';
import 'package:wenznote/service/file/file_manager.dart';
import 'package:wenznote/service/service_manager.dart';
import 'package:super_drag_and_drop/super_drag_and_drop.dart';
import 'package:uuid/uuid.dart';
import 'package:window_manager/window_manager.dart';

import '../../widgets/doc_title_widget.dart';
Expand Down Expand Up @@ -102,15 +103,17 @@ class WinHomeController extends ServiceManagerController {
void openDoc(DocPO doc, [bool isCreateMode = false]) {
openTab(
id: "doc-${doc.uuid}",
text: DocTitleWidget(controller: DocTitleController(doc),),
text: DocTitleWidget(
controller: DocTitleController(doc),
),
body: WinNoteEditTab(
controller: WinNoteEditTabController(
homeController: this,
doc: doc,
isCreateMode: isCreateMode,
onUpdate: (content) {
docController.reloadDoc(doc,content);
todayController.reloadDoc(doc,content);
docController.reloadDoc(doc, content);
todayController.reloadDoc(doc, content);
getDocTab(doc.uuid)?.controller.notifyListeners();
}),
),
Expand Down
16 changes: 13 additions & 3 deletions lib/app/windows/view/home/win_home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class WinHomePage extends MvcView<WinHomeController> {
);
}

/// app内容:导航栏(左) + 一级内容(中) + 二级内容(右)
Widget buildAppContent(BuildContext context) {
return Obx(() {
return Row(
Expand All @@ -76,6 +77,7 @@ class WinHomePage extends MvcView<WinHomeController> {
});
}

/// 导航栏
Widget buildWindowsNavBar(BuildContext context) {
var theme = fluent.FluentTheme.of(context);
return Container(
Expand Down Expand Up @@ -288,22 +290,24 @@ class WinHomePage extends MvcView<WinHomeController> {
);
}

///主页分割内容界面:导航|内容
Widget buildPage(BuildContext context) {
return Obx(() {
if (controller.showNavPage.isFalse) {
return buildEditPane(context);
return buildEditTabsPane(context);
}
return SplitPane(
primaryIndex: PaneIndex.one,
primaryMinSize: 240,
subMinSize: 340,
onlyShowIndex: controller.showEditPane.value ? null : PaneIndex.one,
one: buildNavPane(context),
two: buildEditPane(context),
two: buildEditTabsPane(context),
);
});
}

///导航内容:今天、笔记、卡片
Widget buildNavPane(BuildContext context) {
var navPages = [
buildTodayPage(context),
Expand All @@ -318,6 +322,7 @@ class WinHomePage extends MvcView<WinHomeController> {
});
}

///今天列表界面
Widget buildTodayPage(BuildContext context) {
var theme = fluent.FluentTheme.of(context);
return DropRegion(
Expand Down Expand Up @@ -374,6 +379,7 @@ class WinHomePage extends MvcView<WinHomeController> {
);
}

/// 编辑列表页面
Widget buildNotePage(BuildContext context) {
var theme = fluent.FluentTheme.of(context);
return Container(
Expand All @@ -393,6 +399,7 @@ class WinHomePage extends MvcView<WinHomeController> {
));
}

/// 卡片列表页面
Widget buildCardPage(BuildContext context) {
var theme = fluent.FluentTheme.of(context);
return Container(
Expand All @@ -412,7 +419,8 @@ class WinHomePage extends MvcView<WinHomeController> {
));
}

Widget buildEditPane(BuildContext context) {
/// 编辑区域,多标签界面
Widget buildEditTabsPane(BuildContext context) {
var theme = fluent.FluentTheme.of(context);
return Material(
color: theme.resources.solidBackgroundFillColorSecondary,
Expand All @@ -427,6 +435,8 @@ class WinHomePage extends MvcView<WinHomeController> {
);
}


/// 侧边导航栏菜单按钮
Widget buildNavMenu(BuildContext context) {
var theme = fluent.FluentTheme.of(context);
return fluent.Tooltip(
Expand Down
2 changes: 0 additions & 2 deletions lib/app/windows/view/tabs/help_tab.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:wenznote/app/windows/controller/home/win_home_controller.dart';
import 'package:wenznote/commons/util/markdown/markdown.dart';
import 'package:wenznote/editor/edit_controller.dart';
import 'package:wenznote/editor/edit_widget.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/app/windows/widgets/custom_tab_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class DragMoveTabView extends StatefulWidget {
this.tabWidthBehavior = TabWidthBehavior.equal,
this.header,
this.footer,
this.closeDelayDuration = const Duration(milliseconds: 400),
this.closeDelayDuration = const Duration(milliseconds: 200),
});

/// The index of the tab to be displayed
Expand Down
118 changes: 107 additions & 11 deletions lib/app/windows/widgets/win_tab_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:wenznote/app/windows/controller/home/win_home_controller.dart';
import 'package:wenznote/app/windows/widgets/custom_tab_view.dart';
import 'package:wenznote/commons/mvc/controller.dart';
import 'package:wenznote/commons/mvc/view.dart';
import 'package:wenznote/editor/widget/drop_menu.dart';
import 'package:wenznote/widgets/mac_window_button.dart';
import 'package:window_manager/window_manager.dart';

Expand All @@ -25,28 +26,50 @@ class WinTabController extends MvcController {

List<CustomTab> tabs = [];

int findTabIndex(String id) {
for (var i = 0; i < tabs.length; i++) {
var tab = tabs[i];
if (tab.key == ValueKey(id)) {
return i;
}
}
return -1;
}

bool isStartTab(int tabIndex) {
return tabIndex == 0;
}

bool isEndTab(int tabIndex) {
return tabIndex == tabs.length - 1;
}

void openTab({
required String id,
required Widget text,
required Widget body,
Widget? icon,
String? semanticLabel,
}) {
for (var i = 0; i < tabs.length; i++) {
var tab = tabs[i];
if (tab.key == ValueKey(id)) {
currentIndex = i;
var body = tab.body;
if (body is Focusable) {
(body as Focusable).focus();
}
notifyListeners();
return;
int tabIndex = findTabIndex(id);
if (tabIndex != -1) {
var tab = tabs[tabIndex];
currentIndex = tabIndex;
var body = tab.body;
if (body is Focusable) {
(body as Focusable).focus();
}
notifyListeners();
return;
}
tabs.add(CustomTab(
key: ValueKey(id),
text: text,
text: GestureDetector(
child: text,
onSecondaryTapUp: (d) {
showTabContextMenu(d, id);
},
),
semanticLabel: semanticLabel,
icon: icon,
body: body,
Expand All @@ -58,6 +81,79 @@ class WinTabController extends MvcController {
notifyListeners();
}

void showTabContextMenu(TapUpDetails event, String id) {
int tabIndex = findTabIndex(id);
showMouseDropMenu(
context,
event.globalPosition & Size.zero,
menus: [
DropMenu(
text: Text("关闭标签页"),
onPress: (ctx) {
hideDropMenu(ctx);
closeTab(id);
},
),
DropMenu(
text: Text("关闭其它标签页"),
onPress: (ctx) {
hideDropMenu(ctx);
closeOtherTabs(tabIndex);
},
),
DropMenu(
text: Text("关闭所有标签页"),
onPress: (ctx) {
hideDropMenu(ctx);
closeAllTab(tabIndex);
},
),
if (!isStartTab(tabIndex))
DropMenu(
text: Text("关闭左侧标签页"),
onPress: (ctx) {
hideDropMenu(ctx);
closeLeftTabs(tabIndex);
},
),
if (!isEndTab(tabIndex))
DropMenu(
text: Text("关闭右侧侧标签页"),
onPress: (ctx) {
hideDropMenu(ctx);
closeRightTabs(tabIndex);
},
),
],
);
}

void closeOtherTabs(int index) {
var current = tabs[index];
tabs.removeWhere((element) => element != current);
currentIndex = 0;
notifyListeners();
}

void closeAllTab(int index) {
currentIndex = 0;
tabs.clear();
notifyListeners();
homeController.showNavPage.value = true;
}

void closeLeftTabs(int index) {
tabs.removeRange(0, index);
currentIndex = 0;
notifyListeners();
}

void closeRightTabs(int index) {
tabs.removeRange(index + 1, tabs.length);
currentIndex = index;
notifyListeners();
}

void closeTab(String id) {
for (var i = 0; i < tabs.length; i++) {
var tab = tabs[i];
Expand Down
1 change: 1 addition & 0 deletions lib/service/edit/doc_edit_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class DocEditService {
}
return !_equalsSnapShot(docBytes ?? Uint8List(0), newBytes);
} catch (e) {
// todo 并doc失败, error: RangeError (index): Index out of range: no indices are valid: 0
printLog("合并doc失败, error: $e");
return false;
}
Expand Down
18 changes: 8 additions & 10 deletions lib/service/sync/doc_snapshot_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,10 @@ class DocSnapshotService {

Future<void> downloadDocFile(String docId) async {
return _downloadLock.synchronized(() async {
var lastQueryTime = downloadDocFileTimeRecord[docId];
if (lastQueryTime != null &&
lastQueryTime < DateTime.now().millisecondsSinceEpoch) {
return;
}
var noteServerUrl = serviceManager.recordSyncService.noteServerUrl;
if (noteServerUrl == null) {
return;
}
// 因为服务器会限制下载文件频率
// 所有创建8秒下载锁,避免重复下载
queryDeltaTimeRecord[docId] =
DateTime.now().millisecondsSinceEpoch + 1000;
var isar = serviceManager.isarService.documentIsar;
var result = await Dio().post(
"$noteServerUrl/snapshot/download/$docId",
Expand Down Expand Up @@ -267,7 +258,7 @@ class DocSnapshotService {
} catch (e) {
// 可能存在yjs合并失败的bug,需要处理yjs类型转换问题
// type 'ContentDeleted' is not a subtype of type 'ContentType' in type cast
printLog("更新doc失败: $e");
printLog("下载文档时,更新ydoc失败: $e");
}
// 写入状态
await isar.writeTxn(() async {
Expand All @@ -277,6 +268,12 @@ class DocSnapshotService {
});
}

/// 通过clientId,updateTime查询需要更新的文档
/// 一旦查询到需要下载的docId,那么这个docId必须下载成功
/// 否则,就会导致文档下载更新失败而无法打开
/// 所以,需要将查询到的需要更新的文档,存到任务队列,直到该文档下载成功
/// 需要注意的时,如果下载文档任务为定时任务,那么在文档编辑过程中不要执行该任务,直到编辑器关闭
/// 编辑过程,用户可以手动下载文档进行更新,或者编辑器会自动触发p2p更新,无需下载文档
Future<List<String>?> queryUpdateList() async {
var token = serviceManager.userService.token;
if (token == null) {
Expand All @@ -303,6 +300,7 @@ class DocSnapshotService {
return null;
}

/// 返回文档状态的最大时间点 clientId,updateTime
Future<Map<String, int>> getClientStates() async {
var isar = serviceManager.isarService.documentIsar;
var states = await isar.docStatePOs.where().findAll();
Expand Down

0 comments on commit 9b03703

Please sign in to comment.