├── .github
└── workflows
│ ├── build-client.yml
│ ├── build-server.yml
│ └── deploy-web.yml
├── .gitignore
├── LICENSE
├── README.md
├── client
├── .gitignore
├── .metadata
├── .vscode
│ └── settings.json
├── analysis_options.yaml
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── vtablet
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable-v21
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── playstore-icon.png
│ │ │ │ ├── values-night
│ │ │ │ └── styles.xml
│ │ │ │ └── values
│ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── assets
│ └── icon
│ │ └── icon_256x.ico
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
├── l10n.yaml
├── lib
│ ├── components
│ │ ├── delay.dart
│ │ └── setting_card.dart
│ ├── configs.dart
│ ├── home.dart
│ ├── l10n
│ │ ├── app_en.arb
│ │ └── app_zh.arb
│ ├── main.dart
│ ├── services
│ │ ├── connect.dart
│ │ └── states.dart
│ ├── setting_screens
│ │ ├── about.dart
│ │ ├── appearance.dart
│ │ ├── connection.dart
│ │ └── control.dart
│ └── vtablet.dart
├── linux
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter
│ │ ├── CMakeLists.txt
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ ├── main.cc
│ ├── my_application.cc
│ └── my_application.h
├── macos
│ ├── .gitignore
│ ├── Flutter
│ │ ├── Flutter-Debug.xcconfig
│ │ ├── Flutter-Release.xcconfig
│ │ └── GeneratedPluginRegistrant.swift
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── app_icon_1024.png
│ │ │ ├── app_icon_128.png
│ │ │ ├── app_icon_16.png
│ │ │ ├── app_icon_256.png
│ │ │ ├── app_icon_32.png
│ │ │ ├── app_icon_512.png
│ │ │ └── app_icon_64.png
│ │ ├── Base.lproj
│ │ └── MainMenu.xib
│ │ ├── Configs
│ │ ├── AppInfo.xcconfig
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── Warnings.xcconfig
│ │ ├── DebugProfile.entitlements
│ │ ├── Info.plist
│ │ ├── MainFlutterWindow.swift
│ │ └── Release.entitlements
├── pubspec.lock
├── pubspec.yaml
├── web
│ ├── .well-known
│ │ └── assetlinks.json
│ ├── favicon.png
│ ├── icons
│ │ ├── Icon-192.png
│ │ ├── Icon-512.png
│ │ ├── Icon-maskable-192.png
│ │ └── Icon-maskable-512.png
│ ├── index.html
│ └── manifest.json
└── windows
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flutter
│ ├── CMakeLists.txt
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugin_registrant.h
│ └── generated_plugins.cmake
│ └── runner
│ ├── CMakeLists.txt
│ ├── Runner.rc
│ ├── flutter_window.cpp
│ ├── flutter_window.h
│ ├── main.cpp
│ ├── resource.h
│ ├── resources
│ └── app_icon.ico
│ ├── runner.exe.manifest
│ ├── utils.cpp
│ ├── utils.h
│ ├── win32_window.cpp
│ └── win32_window.h
└── server
├── .gitattributes
├── .gitignore
├── .vscode
└── tasks.json
├── assets
└── icon_256x.ico
├── bin
├── build.bat
└── run.bat
├── controllers.go
├── docs
└── connect.md
├── go.mod
├── go.sum
├── icon.go
├── internal
├── adb
│ ├── adb.go
│ ├── adb_windows.go
│ └── windows
│ │ ├── AdbWinApi.dll
│ │ ├── AdbWinUsbApi.dll
│ │ ├── NOTICE.txt
│ │ ├── adb.exe
│ │ ├── libwinpthread-1.dll
│ │ └── source.properties
├── logger
│ └── logger.go
├── pointer
│ └── pointer.go
├── protocol
│ └── const.go
└── tools
│ └── cmd.go
├── main.go
├── rsrc.syso
├── services.go
└── tray.go
/.github/workflows/build-client.yml:
--------------------------------------------------------------------------------
1 | name: Build Flutter Client (Android)
2 |
3 | on:
4 | # pull:
5 | # branches: [main]
6 | workflow_dispatch:
7 |
8 | jobs:
9 | Build-Client:
10 | runs-on: ubuntu-latest
11 | defaults:
12 | run:
13 | working-directory: ./client
14 | steps:
15 | - uses: actions/checkout@v3
16 | - uses: actions/setup-java@v2
17 | with:
18 | distribution: 'microsoft'
19 | java-version: '17'
20 | - uses: subosito/flutter-action@v2
21 | with:
22 | channel: 'stable'
23 | flutter-version: 3.27.1
24 | - run: flutter pub get
25 |
26 | # Build Android
27 | - run: flutter build apk
28 | - run: flutter build appbundle
29 |
30 | # Sign Android
31 | - name: Setup build tool version variable
32 | shell: bash
33 | run: |
34 | BUILD_TOOL_VERSION=$(ls /usr/local/lib/android/sdk/build-tools/ | tail -n 1)
35 | echo "BUILD_TOOL_VERSION=$BUILD_TOOL_VERSION" >> $GITHUB_ENV
36 | echo Last build tool version is: $BUILD_TOOL_VERSION
37 | - uses: r0adkll/sign-android-release@v1
38 | name: Sign app APK
39 | id: sign_apk
40 | with:
41 | releaseDirectory: client/build/app/outputs/flutter-apk
42 | signingKeyBase64: ${{ secrets.SIGNING_KEY }}
43 | alias: ${{ secrets.ALIAS }}
44 | keyStorePassword: ${{ secrets.KEY_PASSWORD }}
45 | keyPassword: ${{ secrets.KEY_PASSWORD }}
46 | env:
47 | BUILD_TOOLS_VERSION: ${{ env.BUILD_TOOL_VERSION }}
48 | # - uses: r0adkll/sign-android-release@v1
49 | # name: Sign app AAB
50 | # # ID used to access action output
51 | # id: sign_aab
52 | # with:
53 | # releaseDirectory: client/build/app/outputs/bundle/release
54 | # signingKeyBase64: ${{ secrets.SIGNING_KEY }}
55 | # alias: ${{ secrets.ALIAS }}
56 | # keyStorePassword: ${{ secrets.KEY_PASSWORD }}
57 | # keyPassword: ${{ secrets.KEY_PASSWORD }}
58 | # env:
59 | # BUILD_TOOLS_VERSION: "30.0.2"
60 |
61 | - uses: actions/upload-artifact@v3
62 | with:
63 | name: vTablet_client_apk
64 | path: client/build/app/outputs/flutter-apk/app-release.apk
65 | - uses: actions/upload-artifact@v3
66 | with:
67 | name: vTablet_client_aab
68 | path: client/build/app/outputs/bundle/release/app-release.aab
69 | - uses: actions/upload-artifact@v3
70 | with:
71 | name: vTablet_client_apk_signed
72 | path: ${{steps.sign_apk.outputs.signedReleaseFile}}
73 |
--------------------------------------------------------------------------------
/.github/workflows/build-server.yml:
--------------------------------------------------------------------------------
1 | name: Build Golang Server
2 |
3 | on:
4 | # pull:
5 | # branches: [main]
6 | workflow_dispatch:
7 |
8 | jobs:
9 | Build-Server:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v3
13 | - name: Build
14 | uses: crazy-max/ghaction-xgo@v2
15 | with:
16 | xgo_version: latest
17 | go_version: latest
18 | dest: build
19 | prefix: vtablet
20 | targets: windows/amd64,windows/386
21 | # targets: windows/amd64,windows/386,linux/amd64,darwin/amd64,darwin/arm64
22 | v: true
23 | x: true
24 | race: false
25 | ldflags: -H=windowsgui -s -w
26 | buildmode: default
27 | trimpath: true
28 | working_dir: ./server
29 |
30 | - name: Run UPX
31 | uses: crazy-max/ghaction-upx@v2
32 | with:
33 | version: latest
34 | files: |
35 | server/build/*.exe
36 | args: --best
37 |
38 | - uses: actions/upload-artifact@v3
39 | with:
40 | name: vTablet_server_windows_386
41 | path: server/build/vtablet-windows-386.exe
42 |
43 | - uses: actions/upload-artifact@v3
44 | with:
45 | name: vTablet_server_windows_amd64
46 | path: server/build/vtablet-windows-amd64.exe
--------------------------------------------------------------------------------
/.github/workflows/deploy-web.yml:
--------------------------------------------------------------------------------
1 | name: Deploy Web
2 |
3 | on:
4 | # pull:
5 | # branches: [main]
6 | workflow_dispatch:
7 |
8 | jobs:
9 | Deploy-Web:
10 | runs-on: ubuntu-latest
11 | defaults:
12 | run:
13 | working-directory: ./client
14 | steps:
15 | - uses: actions/checkout@v3
16 | - uses: actions/setup-java@v2
17 | with:
18 | distribution: 'zulu'
19 | java-version: '11'
20 | - uses: subosito/flutter-action@v2
21 | with:
22 | channel: 'stable'
23 | - run: flutter pub get
24 |
25 | # Build Web
26 | - run: flutter build web
27 |
28 | - uses: actions/upload-artifact@v2
29 | with:
30 | name: vTablet_client_web
31 | path: client/build/web
32 |
33 | - name: Publish to Cloudflare Pages
34 | uses: cloudflare/pages-action@1
35 | with:
36 | apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
37 | accountId: 5b730025d7878dcd418287d4e2b66d8e
38 | projectName: vtablet-app
39 | directory: client/build/web
40 | gitHubToken: ${{ secrets.GITHUB_TOKEN }}
41 |
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ./dist/**
2 | /vscode
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Teages
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vTablet
2 |
3 | Use your tablet as your osu digitizer!
4 |
5 | > [!WARNING]
6 | > 3.0 is currently in preview version, and there may be incompatible changes in the transmission protocol. Please be sure to update the server and client at the same time.
7 |
8 | ## Help
9 |
10 | (WIP)
11 |
12 | ## TODO
13 |
14 | - [ ] Update check
15 | - [ ] Benchmarks
16 |
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .packages
31 | .pub-cache/
32 | .pub/
33 | build/**
34 |
35 | # Web related
36 | lib/generated_plugin_registrant.dart
37 |
38 | # Symbolication related
39 | app.*.symbols
40 |
41 | # Obfuscation related
42 | app.*.map.json
43 |
44 | # Android Studio will place build artifacts here
45 | /android/app/debug
46 | /android/app/profile
47 | /android/app/release
48 |
--------------------------------------------------------------------------------
/client/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled.
5 |
6 | version:
7 | revision: f1875d570e39de09040c8f79aa13cc56baab8db1
8 | channel: stable
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
17 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
18 | - platform: android
19 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
20 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
21 | - platform: ios
22 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
23 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
24 | - platform: linux
25 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
26 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
27 | - platform: macos
28 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
29 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
30 | - platform: web
31 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
32 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
33 | - platform: windows
34 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
35 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/client/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.codeActionsOnSave": {
3 | "source.fixAll": "explicit"
4 | },
5 | "cmake.configureOnOpen": false
6 | }
--------------------------------------------------------------------------------
/client/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/client/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/client/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "com.android.application"
3 | id "kotlin-android"
4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
5 | id "dev.flutter.flutter-gradle-plugin"
6 | }
7 |
8 | android {
9 | namespace = "xyz.teages.vtablet"
10 | compileSdk = flutter.compileSdkVersion
11 | ndkVersion = flutter.ndkVersion
12 |
13 | compileOptions {
14 | sourceCompatibility = JavaVersion.VERSION_1_8
15 | targetCompatibility = JavaVersion.VERSION_1_8
16 | }
17 |
18 | kotlinOptions {
19 | jvmTarget = JavaVersion.VERSION_1_8
20 | }
21 |
22 | defaultConfig {
23 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
24 | applicationId = "xyz.teages.vtablet"
25 | // You can update the following values to match your application needs.
26 | // For more information, see: https://flutter.dev/to/review-gradle-config.
27 | minSdk = flutter.minSdkVersion
28 | targetSdk = flutter.targetSdkVersion
29 | versionCode = flutter.versionCode
30 | versionName = flutter.versionName
31 | }
32 |
33 | buildTypes {
34 | release {
35 | // TODO: Add your own signing config for the release build.
36 | // Signing with the debug keys for now, so `flutter run --release` works.
37 | signingConfig = signingConfigs.debug
38 | }
39 | }
40 | }
41 |
42 | flutter {
43 | source = "../.."
44 | }
45 |
--------------------------------------------------------------------------------
/client/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/client/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
10 |
18 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
42 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/client/android/app/src/main/kotlin/com/example/vtablet/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package xyz.teages.vtablet
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/client/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/client/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/playstore-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/android/app/src/main/res/playstore-icon.png
--------------------------------------------------------------------------------
/client/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/client/android/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #78C2EF
4 |
--------------------------------------------------------------------------------
/client/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/client/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/client/android/build.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | }
6 | }
7 |
8 | rootProject.buildDir = "../build"
9 | subprojects {
10 | project.buildDir = "${rootProject.buildDir}/${project.name}"
11 | }
12 | subprojects {
13 | project.evaluationDependsOn(":app")
14 | }
15 |
16 | tasks.register("clean", Delete) {
17 | delete rootProject.buildDir
18 | }
19 |
--------------------------------------------------------------------------------
/client/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/client/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
6 |
--------------------------------------------------------------------------------
/client/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }()
9 |
10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
11 |
12 | repositories {
13 | google()
14 | mavenCentral()
15 | gradlePluginPortal()
16 | }
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
21 | id "com.android.application" version "8.1.0" apply false
22 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false
23 | }
24 |
25 | include ":app"
26 |
--------------------------------------------------------------------------------
/client/assets/icon/icon_256x.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/assets/icon/icon_256x.ico
--------------------------------------------------------------------------------
/client/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/client/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 9.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/client/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/client/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/client/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/client/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Teages/vTablet/a46e1fcf721593f0824f74c6285591b53e5b09f1/client/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/client/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/client/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/client/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/client/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Vtablet
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | vtablet
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 | CADisableMinimumFrameDurationOnPhone
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/client/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/client/l10n.yaml:
--------------------------------------------------------------------------------
1 | arb-dir: lib/l10n
2 | template-arb-file: app_zh.arb
3 | output-localization-file: localizations.dart
--------------------------------------------------------------------------------
/client/lib/components/delay.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:vtablet/services/connect.dart';
3 |
4 | class DelayDialog extends Container {
5 | DelayDialog({
6 | Key? key,
7 | Function()? onClick,
8 | }) : super(
9 | key: key,
10 | child: ValueListenableBuilder(
11 | valueListenable: VTabletWS.delay,
12 | builder: (context, value, child) => ElevatedButton(
13 | onPressed: onClick ?? () {},
14 | style: ElevatedButton.styleFrom(
15 | backgroundColor: getSignalColor(VTabletWS.delay.value),
16 | foregroundColor: Colors.black,
17 | ),
18 | child: Text("${VTabletWS.delay.value} ms"),
19 | ),
20 | ));
21 | static Color getSignalColor(delay) {
22 | if (delay > 40 || delay < 0) {
23 | return const Color.fromARGB(255, 249, 142, 142);
24 | }
25 | if (delay > 15) {
26 | return Colors.yellowAccent;
27 | }
28 | return Colors.greenAccent;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/client/lib/components/setting_card.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CardWithTitle extends StatelessWidget {
4 | const CardWithTitle({
5 | super.key,
6 | required this.title,
7 | required this.content,
8 | });
9 |
10 | final String title;
11 | final List content;
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return Container(
16 | child: Column(
17 | crossAxisAlignment: CrossAxisAlignment.start,
18 | children: [
19 | Text(
20 | title,
21 | style: Theme.of(context).textTheme.headlineSmall,
22 | ),
23 | Card(
24 | elevation: 1.0,
25 | child: Container(
26 | width: double.infinity,
27 | padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
28 | alignment: Alignment.topLeft,
29 | child: Wrap(
30 | spacing: 0,
31 | children: content,
32 | ),
33 | ),
34 | ),
35 | const SizedBox(
36 | height: 20,
37 | ),
38 | ],
39 | ),
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/client/lib/configs.dart:
--------------------------------------------------------------------------------
1 | import 'package:vtablet/services/states.dart';
2 |
3 | class Configs {
4 | static final serverHostSaved =
5 | _initConfig("server.host", "localhost:23052");
6 | static final serverHost =
7 | _initState("server.host", serverHostSaved.get());
8 |
9 | static final preventSleep = _initConfig("other.preventSleep", true);
10 |
11 | static final screenUidSaved = _initConfig("aria.screenId", "");
12 | static final screenUid = _initState("aria.screenId", "");
13 |
14 | static final ariaScale = _initConfig("aria.scale", 0.8);
15 | static final ariaOffsetX = _initConfig("aria.offset.x", 0);
16 | static final ariaOffsetY = _initConfig("aria.offset.y", 0);
17 | // static final ariaTransform = _initConfig("aria.transform", 1);
18 | static final ariaRatio = _initConfig("aria.ratio", 16 / 9);
19 |
20 | static final inputEnablePen = _initConfig("input.enable.pen", true);
21 | static final inputEnableTouch =
22 | _initConfig("input.enable.touch", false);
23 | static final inputEnableMouse =
24 | _initConfig("input.enable.mouse", false);
25 |
26 | static final inputIgnoreClick = _initConfig("input.ignoreClick", false);
27 |
28 | static final delay = _initState("delay", -1);
29 |
30 | static _Config _initConfig(String key, T defaultValue) {
31 | _Config config = _Config(key, defaultValue);
32 | return config;
33 | }
34 |
35 | static _State _initState(String key, T defaultValue) {
36 | _State state = _State(key, defaultValue);
37 | return state;
38 | }
39 | }
40 |
41 | class _Config {
42 | final String _key;
43 | final T _defaultValue;
44 |
45 | _Config(String key, T defaultValue)
46 | : _key = key,
47 | _defaultValue = defaultValue;
48 |
49 | T get() {
50 | return ConfigManager.getConfig(_key, _defaultValue);
51 | }
52 |
53 | set(T newValue) {
54 | ConfigManager.setConfig(_key, newValue);
55 | }
56 | }
57 |
58 | class _State {
59 | final String _key;
60 | final T _defaultValue;
61 |
62 | _State(String key, T defaultValue)
63 | : _key = key,
64 | _defaultValue = defaultValue;
65 |
66 | T get() {
67 | return StateManager.getConfig(_key, _defaultValue);
68 | }
69 |
70 | set(T newValue) {
71 | StateManager.setConfig(_key, newValue);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/client/lib/home.dart:
--------------------------------------------------------------------------------
1 | import 'package:app_links/app_links.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_gen/gen_l10n/localizations.dart';
4 | import 'package:logger/logger.dart';
5 |
6 | import 'package:fullscreen_window/fullscreen_window.dart';
7 | import 'package:vtablet/configs.dart';
8 | import 'package:vtablet/services/connect.dart';
9 | import 'package:vtablet/setting_screens/about.dart';
10 | import 'package:vtablet/setting_screens/appearance.dart';
11 | import 'package:vtablet/setting_screens/control.dart';
12 | import 'package:vtablet/vtablet.dart';
13 | import 'package:wakelock_plus/wakelock_plus.dart';
14 |
15 | import 'setting_screens/connection.dart';
16 |
17 | class Home extends StatefulWidget {
18 | const Home({
19 | super.key,
20 | required this.title,
21 | required this.handleBrightnessChange,
22 | });
23 |
24 | final String title;
25 | final void Function() handleBrightnessChange;
26 |
27 | @override
28 | State createState() => _HomeState();
29 | }
30 |
31 | class _HomeState extends State {
32 | int currentPageIndex = 0;
33 |
34 | _HomeState() : super() {
35 | () async {
36 | try {
37 | Uri? startUrl;
38 | try {
39 | startUrl = await AppLinks().getLatestLink();
40 | } catch (e) {
41 | // Ignore
42 | }
43 | var server = startUrl?.queryParameters["server"] ??
44 | Configs.serverHostSaved.get();
45 | setState(() {
46 | Configs.serverHost.set(server);
47 | });
48 | var ans = await Services.fetchData();
49 | if (context.mounted) {
50 | if (ans) {
51 | ScaffoldMessenger.of(context).showSnackBar(SnackBar(
52 | content: Text(AppLocalizations.of(context)!
53 | .succeedConnected(Configs.serverHost.get())),
54 | duration: const Duration(seconds: 1),
55 | ));
56 | }
57 | setState(() {});
58 | }
59 | } catch (e) {
60 | // Ignore
61 | Logger().i(e);
62 | }
63 | }();
64 | }
65 |
66 | @override
67 | Widget build(BuildContext context) {
68 | return Scaffold(
69 | appBar: AppBar(
70 | title: Text(widget.title),
71 | actions: [
72 | IconButton(
73 | onPressed: widget.handleBrightnessChange,
74 | icon: const Icon(Icons.dark_mode))
75 | ],
76 | ),
77 | floatingActionButton: currentPageIndex == 0
78 | ? ValueListenableBuilder(
79 | valueListenable: VTabletWS.state,
80 | builder: (context, value, child) {
81 | return FloatingActionButton.extended(
82 | onPressed: () {
83 | if (VTabletWS.state.value == WsConnectionState.connected) {
84 | WakelockPlus.toggle(enable: Configs.preventSleep.get());
85 | Navigator.push(
86 | context,
87 | MaterialPageRoute(
88 | builder: (context) => VTabletPage(),
89 | ),
90 | );
91 | FullScreenWindow.setFullScreen(true);
92 | } else {
93 | ScaffoldMessenger.of(context).showSnackBar(
94 | SnackBar(
95 | content: Text(
96 | AppLocalizations.of(context)!.connectFirstPlease),
97 | duration: const Duration(seconds: 1),
98 | ),
99 | );
100 | }
101 | },
102 | label: const Text('Start'),
103 | icon: const Icon(Icons.play_arrow),
104 | backgroundColor:
105 | VTabletWS.state.value == WsConnectionState.connected
106 | ? null
107 | // : Theme.of(context).disabledColor,
108 | : Colors.grey,
109 | );
110 | },
111 | )
112 | : null,
113 | bottomNavigationBar: MediaQuery.of(context).size.width < 640
114 | ? NavigationBar(
115 | onDestinationSelected: (int index) {
116 | setState(() {
117 | currentPageIndex = index;
118 | });
119 | },
120 | selectedIndex: currentPageIndex,
121 | destinations: const [
122 | ConnectionDestination(),
123 | ControlDestination(),
124 | AppearanceDestination(),
125 | AboutDestination(),
126 | ],
127 | )
128 | : null,
129 | body: Row(
130 | mainAxisSize: MainAxisSize.max,
131 | children: [
132 | if (MediaQuery.of(context).size.width >= 640)
133 | NavigationRail(
134 | selectedIndex: currentPageIndex,
135 | onDestinationSelected: (int index) {
136 | setState(() {
137 | currentPageIndex = index;
138 | });
139 | },
140 | labelType: NavigationRailLabelType.all,
141 | // navigation rail items
142 | destinations: [
143 | connectionRailDestination(context),
144 | controlRailDestination(context),
145 | appearanceRailDestination(context),
146 | aboutRailDestination(context),
147 | ],
148 | ),
149 | Expanded(
150 | child: [
151 | const ConnectionPage(),
152 | const ControlPage(),
153 | const AppearancePage(),
154 | const AboutPage(),
155 | ][currentPageIndex],
156 | ),
157 | ],
158 | ),
159 | );
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/client/lib/l10n/app_en.arb:
--------------------------------------------------------------------------------
1 | {
2 | "aboutPageTitle": "About",
3 | "aboutSoftwareInfoTitle": "App Info",
4 | "aboutUpdateCheckTitle": "Update Check",
5 | "aboutDonateTitle": "Donate",
6 | "aboutGithubBtn": "Visit GitHub repo",
7 |
8 | "appearancePageTitle": "Appearance",
9 | "appearancePageContext": "Apprarance is not ready yet",
10 |
11 |
12 | "connectionPageTitle": "Connection",
13 | "connectionFirstTitle": "Connect to server",
14 | "connectionServer": "Server",
15 | "connectionConnectBtn": "Connect",
16 | "connectionDisconnectBtn": "Disconnect",
17 | "connectionState": "Connect State",
18 | "connectionStateConnected": "Connected",
19 | "connectionStateDisconnected": "Disconnected",
20 | "connectionMonitor": "Monitor {uid}: {width}x{height}",
21 | "@connectionMonitor": {
22 | "placeholders": {
23 | "uid": {
24 | "type": "String",
25 | "example": "ffffff"
26 | },
27 | "width": {
28 | "type": "int",
29 | "example": "1920"
30 | },
31 | "height": {
32 | "type": "int",
33 | "example": "1080"
34 | }
35 | }
36 | },
37 | "connectionReconnectBtn": "Reconnect",
38 |
39 | "controlPageTitle": "Control",
40 | "controlAriaTitle": "Input Aria",
41 | "controlAriaScaleLabel": "Scale",
42 | "controlAriaOffsetXLabel": "Offset X",
43 | "controlAriaOffsetYLabel": "Offset Y",
44 | "controlInputTypeTitle": "Input Type",
45 | "controlInputTypenamePen": "Pen",
46 | "controlInputTypenameTouch": "Touch",
47 | "controlInputTypenameMouse": "Mouse",
48 | "controlInputIgnoreClick": "Ignore pressure input",
49 | "controlOtherTitle": "Other",
50 | "controlPreventSleep": "Prevent phone/tablet from sleeping",
51 |
52 | "clickAgainToExit": "Click again to exit.",
53 | "lostConnect": "Disconnected to server",
54 | "connectFirstPlease": "Please connect first",
55 |
56 | "succeedConnected": "Server found: {url}",
57 | "@succeedConnected": {
58 | "placeholders": {
59 | "url": {
60 | "type": "String",
61 | "example": "localhost"
62 | }
63 | }
64 | },
65 | "failedConnected": "Server not responding: {url}",
66 | "@failedConnected": {
67 | "placeholders": {
68 | "url": {
69 | "type": "String",
70 | "example": "localhost"
71 | }
72 | }
73 | },
74 |
75 | "helpBtn": "Help"
76 | }
--------------------------------------------------------------------------------
/client/lib/l10n/app_zh.arb:
--------------------------------------------------------------------------------
1 | {
2 | "aboutPageTitle": "关于",
3 | "aboutSoftwareInfoTitle": "软件信息",
4 | "aboutUpdateCheckTitle": "更新检查",
5 | "aboutDonateTitle": "捐赠",
6 | "aboutGithubBtn": "访问项目 GitHub 仓库",
7 |
8 | "appearancePageTitle": "外观",
9 | "appearancePageContext": "外观设置正在准备中",
10 |
11 |
12 | "connectionPageTitle": "连接",
13 | "connectionFirstTitle": "连接服务器",
14 | "connectionServer": "服务器",
15 | "connectionConnectBtn": "连接",
16 | "connectionDisconnectBtn": "断开连接",
17 | "connectionState": "连接状态",
18 | "connectionStateConnected": "已连接",
19 | "connectionStateDisconnected": "未连接",
20 | "connectionMonitor": "显示器 {uid}: {width}x{height}",
21 | "@connectionMonitor": {
22 | "placeholders": {
23 | "uid": {
24 | "type": "String",
25 | "example": "ffffff"
26 | },
27 | "width": {
28 | "type": "int",
29 | "example": "1920"
30 | },
31 | "height": {
32 | "type": "int",
33 | "example": "1080"
34 | }
35 | }
36 | },
37 | "connectionReconnectBtn": "重新连接",
38 |
39 | "controlPageTitle": "控制",
40 | "controlAriaTitle": "输入区域",
41 | "controlAriaScaleLabel": "缩放",
42 | "controlAriaOffsetXLabel": "X 偏移",
43 | "controlAriaOffsetYLabel": "Y 偏移",
44 | "controlInputTypeTitle": "输入类型",
45 | "controlInputTypenamePen": "笔",
46 | "controlInputTypenameTouch": "触摸",
47 | "controlInputTypenameMouse": "鼠标",
48 | "controlInputIgnoreClick": "忽略压力信息",
49 | "controlOtherTitle": "其他设置",
50 | "controlPreventSleep": "阻止手机/平板休眠",
51 |
52 | "clickAgainToExit": "再点一次以退出",
53 | "lostConnect": "与服务器断开连接",
54 | "connectFirstPlease": "请先连接",
55 |
56 | "succeedConnected": "找到服务器: {url}",
57 | "@succeedConnected": {
58 | "placeholders": {
59 | "url": {
60 | "type": "String",
61 | "example": "localhost"
62 | }
63 | }
64 | },
65 | "failedConnected": "服务器未响应: {url}",
66 | "@failedConnected": {
67 | "placeholders": {
68 | "url": {
69 | "type": "String",
70 | "example": "localhost"
71 | }
72 | }
73 | },
74 |
75 | "helpBtn": "帮助文档"
76 | }
--------------------------------------------------------------------------------
/client/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/scheduler.dart';
3 | import 'package:vtablet/services/states.dart';
4 | import 'package:flutter_localizations/flutter_localizations.dart';
5 | import 'package:flutter_gen/gen_l10n/localizations.dart';
6 |
7 | import 'home.dart';
8 |
9 | void main() {
10 | runApp(const App());
11 | ConfigManager.initManager();
12 | }
13 |
14 | class App extends StatefulWidget {
15 | const App({super.key});
16 |
17 | @override
18 | State createState() => _AppState();
19 | }
20 |
21 | class _AppState extends State {
22 | bool useMaterial3 = true;
23 | ThemeMode themeMode = ThemeMode.system;
24 |
25 | bool get useLightMode {
26 | switch (themeMode) {
27 | case ThemeMode.system:
28 | return SchedulerBinding.instance.window.platformBrightness ==
29 | Brightness.light;
30 | case ThemeMode.light:
31 | return true;
32 | case ThemeMode.dark:
33 | return false;
34 | }
35 | }
36 |
37 | void handleBrightnessChange() {
38 | setState(() {
39 | themeMode = useLightMode ? ThemeMode.dark : ThemeMode.light;
40 | });
41 | }
42 |
43 | @override
44 | Widget build(BuildContext context) {
45 | return MaterialApp(
46 | debugShowCheckedModeBanner: false,
47 | title: 'vTablet',
48 | localizationsDelegates: const [
49 | AppLocalizations.delegate,
50 | GlobalMaterialLocalizations.delegate,
51 | GlobalWidgetsLocalizations.delegate,
52 | GlobalCupertinoLocalizations.delegate,
53 | ],
54 | supportedLocales: const [
55 | Locale('zh'), // Chinese
56 | Locale('en'), // English
57 | ],
58 | themeMode: themeMode,
59 | theme: ThemeData(
60 | // colorSchemeSeed: colorSelected.color,
61 | useMaterial3: useMaterial3,
62 | brightness: Brightness.light,
63 | ),
64 | darkTheme: ThemeData(
65 | // colorSchemeSeed: colorSelected.color,
66 | useMaterial3: useMaterial3,
67 | brightness: Brightness.dark,
68 | ),
69 | home: Home(
70 | title: "vTablet",
71 | handleBrightnessChange: handleBrightnessChange,
72 | ),
73 | );
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/client/lib/services/connect.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:convert';
3 |
4 | import 'package:flutter/foundation.dart';
5 | import 'package:logger/logger.dart';
6 | import 'package:vtablet/configs.dart';
7 | import 'package:http/http.dart' as http;
8 | import 'package:web_socket_channel/io.dart';
9 | import 'package:web_socket_channel/web_socket_channel.dart';
10 |
11 | class ScreenData {
12 | final String uid;
13 | final String path;
14 | final int width;
15 | final int height;
16 |
17 | ScreenData(this.uid, this.path, this.width, this.height);
18 |
19 | ScreenData.fromJson(Map json)
20 | : uid = json['uid'],
21 | path = json['path'],
22 | width = json['width'],
23 | height = json['height'];
24 |
25 | List