feat: update README.

dev
DebuggerX 3 years ago
parent 6a936e7364
commit 25675aae8d

1
.gitignore vendored

@ -1,2 +1,3 @@
.idea/
.vscode/
db_data/

@ -1,2 +1,141 @@
# DDE Gesture Manager
专为 DDE 桌面环境打造的触摸板手势管理工具
![logo](https://github.com/debuggerx01/dde_gesture_manager/blob/master/app/web/icons/Icon-192.png?raw=true)
专为 [DDE](https://www.deepin.org/zh/dde/) 桌面环境打造的触摸板手势管理工具缩写dgm客户端使用 [Flutter](https://flutter.dev/) 构建,后端技术栈为 [dart](https://dart.dev/) 的 [Angel3 框架](https://github.com/dukefirehawk/angel) + [PostgreSQL](https://www.postgresql.org/) + [Redis](https://redis.io/) + docker。
# DEMO
[DDE手势管理器-web版](http://www.debuggerx.com/dgm_web/#/)
# BUILD/RUN
## api
- 使用docker(推荐)
首先安装 docker 及 docker-compose然后在`/api`目录下执行:
```shell
bash start.sh
```
- 手动运行
1. 首先配置 dart 环境(如果已经配置 flutter 开发环境则无需再配置):
[Dart SDK overview](https://dart.dev/tools/sdk)
2. 安装项目依赖,运行代码生成命令:
在`/api`目录下执行:
```shell
bash source_gen.sh
```
3. 安装 PostgreSQL 及 Redis
- [PostgreSQL Downloads](https://www.postgresql.org/download/)
- [Redis Downloads](https://redis.io/download)
然后在 `/config/development.yaml` 设置如下配置:
```yaml
# Development-only server configuration.
debug: true
postgres:
host: [db host]
port: 5432
database_name: gesture_manager
username: postgres
password: [db password]
use_ssl: false
time_zone: Asia/Shanghai
redis:
host: [redis host]
port: 6379
password: [redis password]
smtp:
username: [smtp account name]
password: [smtp account password]
host: [smtp server host]
```
4. 设置数据库
- 登录数据库,创建名为 `gesture_manager` 的数据库
```sql
create database gesture_manager;
```
- 运行 Migration
```bash
dart bin/migrate.dart
```
5. 运行 api
```bash
dart bin/dev.dart
```
## app
1. 配置 flutter 开发环境,并启用 Linux 支持:
- [Linux install](https://docs.flutter.dev/get-started/install/linux)
- [Additional Linux requirements](https://docs.flutter.dev/get-started/install/linux#additional-linux-requirements)
2. 修改服务器连接地址
`/api` 目录下修改 `lib/apis.dart`:
```dart
class Apis {
static const apiScheme = 'http';
static const apiHost = 'localhost'; // 设置为api的地址
static const apiPort = 3000; // 设置为api监听的端口
static const appNewVersionUrl = 'https://www.debuggerx.com';
……
}
```
3. 安装项目依赖,运行代码生成命令:
在`/app`目录下执行:
```shell
bash source_gen.sh
```
4. 运行app项目
- Linux
```shell
flutter run -d linux
```
- web:
```shell
flutter run -d chrome
```
# RoadMap
- [ ] 方案下载功能实现
- [ ] 方案应用功能实现
- [ ] BugFix
- [ ] 浅色模式界面优化
- [ ] 打包上架 Deepin/UOS 应用商店
# FAQ
- Q为什么要开发这个工具
A本人是 [Deepin Linux](https://www.deepin.org/zh/) 的老粉了,日常学习工作和生活娱乐几乎完全在 Deepin/UOS 系统下进行。同时我还是个手势重度依赖者,除了鼠标手势,对笔记本的触摸板手势一样有很强的自定义需求。但是从 Deepin 系统增加手势功能到如今也有5年多了官方一直没有在系统层面给出自定义触摸板手势的功能入口我不得不经常通过手工修改系统手势配置文件的方式来实现自定义。但是长久以来一方面是自己每次新装系统都需要重新设置一方面是不断看到论坛和用户群有朋友反馈询问修改方法遂决定动手写一个方便使用并支持配置分享下载的GUI工具
- Q为什么使用 flutter 开发而不是 Qt/DTK/GTK ……
A因为本人对 flutter 比较熟悉有4年多的研究积累而且对于 flutter 的跨平台效果非常看好而C/C++的经验相对缺乏又恰逢2021下半年这个时间点google官方的一大重点就是对桌面应用开发的支持于是决定尝试通过使用 flutter 实现本工具。
- Q为何还要兼容开发Web版本
A得益于 flutter 的跨平台能力,在开发 Linux 桌面版应用的基础上,可以以很低的成本同步开发出 Web 版,于是一方面出于技术探索的目的,从一开始的功能规划我就将 Web 支持放在了基础需求中。另外Web 版还有三个明显的好处:
1. 用户可以不必安装桌面应用,仅仅通过浏览器打开网页就能体验本工具的功能,方便了用户预览体验,也方便本项目的转发推广;
2. 由于 UOS 系统默认是锁 root 权限的,某些情况下的用户(比如机关单位的普通员工)可能不方便安装运行第三方软件,虽然我有将本工具上架 UOS 软件商店的打算,但是并不一定能够保证及时更新,所以此时可以通过使用 Web 版来实现和桌面版相同的功能和接近的体验;
3. 还有一部分用户可能使用的是国产CPU可能并不是 flutter 的编译工具所支持的,或者虽然 flutter 支持,但是由于我没有对应的机器进项编译打包,所以可能暂时无法为这些用户提供二进制的程序使用,此时这些用户一样可以通过使用 Web 版来解决。

@ -8,7 +8,7 @@ var lightTheme = ThemeData.light().copyWith(
iconTheme: IconThemeData(
color: Color(0xff414d68),
),
dividerColor: Color(0xfff3f3f3),
dividerColor: Colors.grey.shade600,
textTheme: ThemeData.light().textTheme.copyWith(
headline1: TextStyle(
color: Color(0xff414d68),

@ -4,6 +4,7 @@ import 'package:dde_gesture_manager/models/content_layout.provider.dart';
import 'package:dde_gesture_manager/models/scheme.dart';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:uuid/uuid.dart';
extension EnumByName<T extends Enum> on Iterable<T> {
@ -29,9 +30,9 @@ class H {
initSharedPreference() async {
_sp = await SharedPreferences.getInstance();
}
late BuildContext _topContext;
BuildContext get topContext => _topContext;
DateTime? lastCheckAuthStatusTime;
@ -114,6 +115,14 @@ class H {
gestureProp.direction = tree.availableNode.availableNode.availableNode.direction;
return gestureProp;
}
static void launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
}
class PreferredPanelsStatus {

@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:dde_gesture_manager/constants/constants.dart';
import 'package:dde_gesture_manager/extensions.dart';
import 'package:dde_gesture_manager/models/settings.provider.dart';
import 'package:dde_gesture_manager/utils/helper.dart';
import 'package:dde_gesture_manager/utils/notificator.dart';
import 'package:flutter/material.dart';
import 'package:markdown_editor_ot/markdown_editor.dart';
@ -36,14 +37,6 @@ class _DMarkdownFieldState extends State<DMarkdownField> {
super.initState();
}
_launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
@override
void didUpdateWidget(covariant DMarkdownField oldWidget) {
if (oldWidget.initText != widget.initText) {
@ -82,7 +75,7 @@ class _DMarkdownFieldState extends State<DMarkdownField> {
child: MdPreview(
text: _previewText ?? '',
padding: EdgeInsets.only(left: 15),
onTapLink: _launchURL,
onTapLink: H.launchURL,
onCodeCopied: () {
Notificator.success(
context,

@ -4,6 +4,7 @@ import 'package:dde_gesture_manager/constants/constants.dart';
import 'package:dde_gesture_manager/http/api.dart';
import 'package:dde_gesture_manager/models/configs.provider.dart';
import 'package:dde_gesture_manager/models/settings.provider.dart';
import 'package:dde_gesture_manager/utils/helper.dart';
import 'package:dde_gesture_manager/widgets/dde_button.dart';
import 'package:dde_gesture_manager_api/models.dart';
import 'package:flutter/material.dart';
@ -131,17 +132,17 @@ class _MarketWidgetState extends State<MarketWidget> {
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: .3,
color: context.t.dividerColor,
),
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
child: Column(
children: [
Flexible(
child: Column(
children: [
Flexible(
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: .3,
color: context.t.dividerColor,
),
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 1, vertical: 2),
child: ListView.builder(
@ -221,8 +222,19 @@ class _MarketWidgetState extends State<MarketWidget> {
),
),
),
Divider(thickness: .5),
Flexible(
),
Container(height: 10),
Flexible(
child: Container(
height: double.infinity,
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(
width: .3,
color: context.t.dividerColor,
),
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
child: Padding(
padding: const EdgeInsets.only(left: 8),
child: MdPreview(
@ -236,12 +248,13 @@ class _MarketWidgetState extends State<MarketWidget> {
),
errorWidget: (context, url, error) => const Icon(Icons.error),
),
onTapLink: H.launchURL,
onCodeCopied: () {},
),
),
),
],
),
),
],
),
),
Padding(

@ -7,6 +7,7 @@ import 'package:dde_gesture_manager/http/api.dart';
import 'package:dde_gesture_manager/models/configs.provider.dart';
import 'package:dde_gesture_manager/models/scheme_list_refresh_key.provider.dart';
import 'package:dde_gesture_manager/models/settings.provider.dart';
import 'package:dde_gesture_manager/utils/helper.dart';
import 'package:dde_gesture_manager/utils/notificator.dart';
import 'package:dde_gesture_manager/utils/simple_throttle.dart';
import 'package:dde_gesture_manager_api/models.dart';
@ -141,17 +142,17 @@ class _MeWidgetState extends State<MeWidget> {
),
),
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: .3,
color: context.t.dividerColor,
),
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
child: Column(
children: [
Flexible(
child: Column(
children: [
Flexible(
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: .3,
color: context.t.dividerColor,
),
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 1, vertical: 2),
child: ListView.builder(
@ -225,12 +226,24 @@ class _MeWidgetState extends State<MeWidget> {
),
),
),
Divider(thickness: .5),
Flexible(
),
Container(height: 10),
Flexible(
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
border: Border.all(
width: .3,
color: context.t.dividerColor,
),
borderRadius: BorderRadius.circular(defaultBorderRadius),
),
child: Padding(
padding: const EdgeInsets.only(left: 8),
child: MdPreview(
text: _schemes.firstWhereOrNull((e) => e.uuid == _selected)?.description ?? '',
onTapLink: H.launchURL,
widgetImage: (imageUrl) => CachedNetworkImage(
imageUrl: imageUrl,
placeholder: (context, url) => const SizedBox(
@ -243,9 +256,9 @@ class _MeWidgetState extends State<MeWidget> {
onCodeCopied: () {},
),
),
)
],
),
),
)
],
),
),
Padding(

Loading…
Cancel
Save