diff --git a/.eslintrc.json b/.eslintrc.json index f2dd2be..0238834 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,48 +1,40 @@ { - "env": { - "browser": true, - "es2021": true, - "node": true + "env": { + "browser": true, + "es2021": true, + "node": true + }, + "extends": ["eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended", "prettier"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true }, - "extends": [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:@typescript-eslint/recommended", - "prettier" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": "latest", - "sourceType": "module" - }, - "plugins": [ - "react", - "@typescript-eslint" - ], - "rules": { - "@typescript-eslint/ban-types": [ - "warn", - { - "extendDefaults": true, - "types": { - "{}": false - } - } - ], - "@typescript-eslint/no-unused-vars": [ - "warn", - { - "argsIgnorePattern": "^_", - "varsIgnorePattern": "^_" - } - ] - }, - "settings": { - "react": { - "version": "detect" + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["react", "@typescript-eslint"], + "rules": { + "@typescript-eslint/ban-types": [ + "warn", + { + "extendDefaults": true, + "types": { + "{}": false } + } + ], + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_" + } + ] + }, + "settings": { + "react": { + "version": "detect" } + } } diff --git a/.github/workflows/backend-checks.yml b/.github/workflows/backend-checks.yml index a66b210..3274088 100644 --- a/.github/workflows/backend-checks.yml +++ b/.github/workflows/backend-checks.yml @@ -3,12 +3,12 @@ name: Check backend on: push: paths: - - ".github/workflows/backend-checks.yml" - - "src-tauri/**" + - '.github/workflows/backend-checks.yml' + - 'src-tauri/**' pull_request: paths: - - ".github/workflows/backend-checks.yml" - - "src-tauri/**" + - '.github/workflows/backend-checks.yml' + - 'src-tauri/**' concurrency: group: ${{ github.ref }}-${{ github.workflow }} @@ -59,4 +59,3 @@ jobs: name: clippy (${{ runner.os }}) token: ${{ secrets.GITHUB_TOKEN }} args: --manifest-path ./src-tauri/Cargo.toml --no-default-features -- -D warnings - diff --git a/.github/workflows/frontend-checks.yml b/.github/workflows/frontend-checks.yml index 4535d49..993b279 100644 --- a/.github/workflows/frontend-checks.yml +++ b/.github/workflows/frontend-checks.yml @@ -3,20 +3,20 @@ name: Check frontend on: push: paths: - - ".github/workflows/frontend-checks.yml" - - "src/**" - - ".eslintrc.json" - - "package.json" - - "tsconfig.json" - - "yarn.lock" + - '.github/workflows/frontend-checks.yml' + - 'src/**' + - '.eslintrc.json' + - 'package.json' + - 'tsconfig.json' + - 'yarn.lock' pull_request: paths: - - ".github/workflows/frontend-checks.yml" - - "src/**" - - ".eslintrc.json" - - "package.json" - - "tsconfig.json" - - "yarn.lock" + - '.github/workflows/frontend-checks.yml' + - 'src/**' + - '.eslintrc.json' + - 'package.json' + - 'tsconfig.json' + - 'yarn.lock' concurrency: group: ${{ github.ref }}-${{ github.workflow }} @@ -34,4 +34,3 @@ jobs: run: yarn tsc --noEmit - name: Run ESLint run: yarn eslint src - diff --git a/README.md b/README.md index 96b7a6c..2e3b963 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,28 @@ # Client Patching Notice + For game versions 2.8 and above, Cultivation automatically makes a small patch to your game client when launching using Grasscutter, and restores it upon closing the game. In theory, you should still be totally safe, however it would be dishonest to not explicitly state that **modifying the game client could, theoretically, lead to a ban if you connect to official servers with it**. It is extremely unlikely AND there are no instances known of it happening, but the possibility exists. # Cultivation + A game launcher designed to easily proxy traffic from anime game to private servers. While the Cultivation repository is **open**. This does **not** mean it has released. Please do **NOT install, download, or use pre-compiled versions of Cultivation found elsewhere**. Only use releases from this GitHub repository. # Table Of Contents -* [Download](#download) -* [Developer Quick-start](#developer-quickstart) - * [Setup](#setup) - * [Building](#building) - * [Code Formatting and Linting](#code-formatting-and-linting) - * [Generating Update Artifacts](#generating-update-artifacts) -* [Theming](#theming) -* [Screenshots](#screenshots) -* [Credits](#credits) +- [Download](#download) +- [Developer Quick-start](#developer-quickstart) + - [Setup](#setup) + - [Building](#building) + - [Code Formatting and Linting](#code-formatting-and-linting) + - [Generating Update Artifacts](#generating-update-artifacts) +- [Theming](#theming) +- [Screenshots](#screenshots) +- [Credits](#credits) # Download + [Find release builds here!](https://github.com/Grasscutters/Cultivation/releases) Once downloaded, extract somewhere and open as administrator. @@ -27,27 +30,33 @@ Once downloaded, extract somewhere and open as administrator. # Developer Quickstart ### Setup -* Install [NodeJS >12](https://nodejs.org/en/) -* Install [yarn](https://classic.yarnpkg.com/lang/en/docs/install) (cry about it `npm` lovers) -* Install [Rust](https://www.rust-lang.org/tools/install) -* `yarn install` -* `yarn start:dev` + +- Install [NodeJS >12](https://nodejs.org/en/) +- Install [yarn](https://classic.yarnpkg.com/lang/en/docs/install) (cry about it `npm` lovers) +- Install [Rust](https://www.rust-lang.org/tools/install) +- `yarn install` +- `yarn start:dev` ### Building + For a release build, + - `yarn build` For a debug build, + - `yarn build --debug` ### Code Formatting and Linting + - `yarn format` - `yarn lint` ### Generating Update Artifacts -* Add the `TAURI_PRIVATE_KEY` as an environment variable with a path to your private key. -* Add the `TAURI_KEY_PASSWORD` as an environment variable with the password for your private key. -* `yarn build` + +- Add the `TAURI_PRIVATE_KEY` as an environment variable with a path to your private key. +- Add the `TAURI_KEY_PASSWORD` as an environment variable with the password for your private key. +- `yarn build` The update will be at `src-tauri/target/(release|debug)/msi/Cultivation_X.X.X_x64_xx-XX.msi.zip` @@ -56,6 +65,7 @@ The update will be at `src-tauri/target/(release|debug)/msi/Cultivation_X.X.X_x6 A full theming reference can be found [here!](/THEMES.md) # Screenshots + ![image](https://user-images.githubusercontent.com/25207995/173211603-e5e85df7-7fd3-430b-9246-749ebbc1e483.png) ![image](https://user-images.githubusercontent.com/25207995/173211543-b7e88943-cfd2-418b-ac48-7f856868129b.png) ![image](https://user-images.githubusercontent.com/25207995/173211561-a1778fdc-5cfe-4687-9a00-44500d29e470.png) @@ -63,8 +73,9 @@ A full theming reference can be found [here!](/THEMES.md) ![image](https://user-images.githubusercontent.com/25207995/173211590-6a2242b5-1e8f-4db9-a5c7-06284688b131.png) ## Credits -* [SpikeHD](https://github.com/SpikeHD): For originally creating **GrassClipper** and creating the amazing UI of Cultivation. -* [KingRainbow44](https://github.com/KingRainbow44): For building a proxy daemon from scratch and integrating it with Cultivation. -* [Benj](https://github.com/4Benj): For assistance in client patching. -* [lilmayofuksu](https://github.com/lilmayofuksu): For assistance in client patching. -* [Tauri](https://tauri.app): For providing an amazing, efficient, and simple desktop application framework/library. + +- [SpikeHD](https://github.com/SpikeHD): For originally creating **GrassClipper** and creating the amazing UI of Cultivation. +- [KingRainbow44](https://github.com/KingRainbow44): For building a proxy daemon from scratch and integrating it with Cultivation. +- [Benj](https://github.com/4Benj): For assistance in client patching. +- [lilmayofuksu](https://github.com/lilmayofuksu): For assistance in client patching. +- [Tauri](https://tauri.app): For providing an amazing, efficient, and simple desktop application framework/library. diff --git a/THEMES.md b/THEMES.md index 4350cd3..2c83157 100644 --- a/THEMES.md +++ b/THEMES.md @@ -2,7 +2,7 @@ 1. Download your favorite theme! (You can find some in the `#themes` channel on Discord) 2. Place the unzipped theme folder inside of `%appdata%/cultivation/themes` (The path should look something like this: `cultivation/themes/theme_name/index.json`) -4. Enable within Cultivation! +3. Enable within Cultivation! # Creating your own theme @@ -16,16 +16,16 @@ You will need CSS and JS experience if you want to do anything cool. `index.json` is where you tell Cultivation which files and images to include. It supports the following properties: -| Property | Description | -| :--- | :--- | -| `name` | The name of the theme. | -| `version` | Not shown anywhere, the version of the theme. | -| `description` | Not shown anywhere, the description of the theme. | -| `includes` | The files and folders to include. | -| `includes.css` | Array of CSS files to include. Example: `css: ["index.css"]` | -| `includes.js` | Array of JS files to includes. Example `js: ["index.js"]` | -| `customBackgroundURL` | A custom image URL to set as the background. Backgrounds that users set in their config supercede this. Example: `"https://website.com/image.png"` | -| `customBackgroundFile` | Path to a custom background image file. Backgrounds that users set in their config supercede this. Example: `"/image.png"` | +| Property | Description | +| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | The name of the theme. | +| `version` | Not shown anywhere, the version of the theme. | +| `description` | Not shown anywhere, the description of the theme. | +| `includes` | The files and folders to include. | +| `includes.css` | Array of CSS files to include. Example: `css: ["index.css"]` | +| `includes.js` | Array of JS files to includes. Example `js: ["index.js"]` | +| `customBackgroundURL` | A custom image URL to set as the background. Backgrounds that users set in their config supercede this. Example: `"https://website.com/image.png"` | +| `customBackgroundFile` | Path to a custom background image file. Backgrounds that users set in their config supercede this. Example: `"/image.png"` | A full, complete `index.json` will look something like this: @@ -55,15 +55,17 @@ Below are some small examples of what you can do: ```css /* Change the font */ body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif !important; } ``` + ```css /* Remove the news section */ .NewsSection { display: none; } ``` + ```css /* Change the right bar width */ .RightBar { @@ -72,6 +74,7 @@ body { ``` ## How can I change XYZ element? + Every element is documented and describe [here](/docs/elementIds.md). Every\* single DOM element is assigned an ID to allow for easy and hyper-specific editing. ## Writing your JS @@ -83,24 +86,26 @@ Below are some examples of what you can do: ```js /* Change the version number every 500ms */ setInterval(() => { - document.getElementById("version").innerHTML = "v" + Math.floor(Math.random() * 100); -}, 500); + document.getElementById('version').innerHTML = 'v' + Math.floor(Math.random() * 100) +}, 500) ``` + ```js /* Load a custom font */ const head = document.head -const link = document.createElement("link") +const link = document.createElement('link') -link.href = "https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" -link.rel = "stylesheet" -link.type = "text/css" +link.href = 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap' +link.rel = 'stylesheet' +link.type = 'text/css' head.appendChild(link) ``` + ```js /* Create a new button that does nothing */ -const newButton = document.createElement("button"); -newButton.innerHTML = "New Button"; +const newButton = document.createElement('button') +newButton.innerHTML = 'New Button' -document.body.appendChild(newButton); +document.body.appendChild(newButton) ``` diff --git a/docs/elementIds.md b/docs/elementIds.md index 8f87a00..1910a61 100644 --- a/docs/elementIds.md +++ b/docs/elementIds.md @@ -1,133 +1,135 @@ # Documentation of Element ID's and Classes for custom theming ## IDs + This does not include commonly used components (buttons, divider lines, commit author and message, etc...) for accessing and modifying those elements, please check `Classes` section bellow. -| #ID | Description | -|----------------------------------------|-----------------------------------------------------------------| -| `#miniDialogContainer` | Main container of MiniDialog | -| `#miniDialogContainerTop` | Affects only top section of MiniDialog | -| `#miniDialogButtonClose` | Close button (SVG) of MiniDialog | -| `#miniDialogContent` | MiniDialog content | -| `#rightBarContainer` | Main container of RightBar | -| `#rightBarContent` | RightBar content | -| `#rightBarButtonDiscord` | Discord button on the RightBar | -| `#rightBarButtonGithub` | Github button on the RightBar | -| `#playButton` | Main container for whole launch buttons section | -| `#serverControls` | Container of "play on grasscutter" checkbox | -| `#enableGC` | "play on grasscutter" checkbox | -| `#ip` | Server ip input if play on grasscutter is enabled | -| `#port` | Server port input if play on grasscutter is enabled | -| `#httpsEnable` | "Enable https" checkbox if play on grasscutter is enabled | -| `#officialPlay` | Launch button | -| `#serverLaunch` | Launch server button | -| `#serverlaunchIcon` | Icon (SVG) of server launch button | -| `#serverConfigContainer` | Main container of server configuration section | -| `#serverLaunchContainer` | Main container of launch buttons (includes launch server) | -| `#topBarContainer` | Main container of launcher TopBar (minimize, exit, settings...) | -| `#title` | Title of the TopBar | -| `#version` | Version of the launcher in TopBar | -| `#topBarButtonContainer` | Container of launcher TopBar buttons only | -| `#closeBtn` | Exit launcher button | -| `#minBtn` | Minimize launcher button | -| `#settingsBtn` | Settings button | -| `#downloadsBtn` | Downloads button (grasscutter resources, grasscutter...) | -| `#newsContainer` | Main container of the news section | -| `#newsTabsContainer` | Container for news tabs | -| `#commits` | News tabs container commits button | -| `#latest_version` | News tabs for latest version button | -| `#newsContent` | Content section of news container | -| `#newsCommitsTable` | Commits table of news section | -| `#downloadMenuContainerGCStable` | Grasscutter stable update container | -| `#downloadMenuLabelGCStable` | Label for stable update button | -| `#downloadMenuButtonGCStable` | Button container for stable update button | -| `#grasscutterStableBtn` | "Update grasscutter stable" button | -| `#downloadMenuContainerGCDev` | Grasscutter development update container | -| `#downloadMenuLabelGCDev` | Label for latest update button | -| `#downloadMenuButtonGCDev` | Button container for latest update button | -| `grasscutterLatestBtn` | "Update grasscutter latest" button | -| `#downloadMenuContainerGCStableData` | Grasscutter stable data update container | -| `#downloadMenuLabelGCStableData` | Label for stable data update | -| `#downloadMenuButtonGCStableData` | Button container for stable data update button | -| `#grasscutterStableRepo` | "Update grasscutter stable data" button | -| `#downloadMenuContainerGCDevData` | Grasscutter latest data update container | -| `#downloadMenuLabelGCDevData` | Label for latest data update | -| `#downloadMenuButtonGCDevData` | Button container for latest data update button | -| `#grasscutterDevRepo` | "Update grasscutter latest data" button | -| `#downloadMenuContainerResources` | Container for grasscutter resources download | -| `#downloadMenuLabelResources` | label for resources download | -| `#downloadMenuButtonResources` | Button container for resources download button | -| `#resourcesBtn` | "Download grasscutter resources" button | -| `#menuContainer` | Generic Popup modal like menu container | -| `#menuContainerTop` | Top section of menu container | -| `#menuHeading` | Menu title | -| `#menuButtonCloseContainer` | Container for menu close button | -| `#menuButtonCloseIcon` | Menu close icon (SVG) | -| `#menuContent` | Content section of the menu | -| `#menuOptionsContainerGameExec` | Container for game executable option section | -| `#menuOptionsLabelGameExec` | Label for game executable option | -| `#menuOptionsDirGameExec` | Set game executable file browser | -| `#menuOptionsContainerGCJar` | Container for grasscutter jar option | -| `#menuOptionsLabelGCJar` | Label for grasscutter jar option | -| `#menuOptionsDirGCJar` | Set grasscutter jar file browser | -| `#menuOptionsContainerToggleEnc` | Container for toggle encryption option | -| `#menuOptionsLabelToggleEnc` | Label for toggle encryption option | -| `#menuOptionsButtonToggleEnc` | Toggle encryption button container | -| `#toggleEnc` | Toggle encryption button | -| `#menuOptionsContainerGCWGame` | Container for "grasscutter with game" option | -| `#menuOptionsLabelGCWDame` | Label for "grasscutter with game" option | -| `#menuOptionsCheckboxGCWGame` | Container for "grasscutter with game" option checkbox | -| `#gcWithGame` | Grasscutter with game checkbox | -| `#menuOptionsContainerThemes` | Container for themes section | -| `#menuOptionsLabelThemes` | Label for set themes option | -| `#menuOptionsSelectThemes` | Container for themes select menu | -| `#menuOptionsSelectMenuThemes` | Set theme select menu | -| `#menuOptionsContainerJavaPath` | Container for Java Path option | -| `#menuOptionsLabelJavaPath` | Label for Java path option | -| `#menuOptionsDirJavaPath` | Container for java path file browser | -| `#menuOptionsContainerBG` | Container for Background option | -| `#menuOptionsLabelBG` | Label for background option | -| `#menuOptionsDirBG` | Container for background url/local path option | -| `#menuOptionsContainerLang` | Container for language change option | -| `#menuOptionsLabelLang` | Label for language change option | -| `#menuOptionsSelectLang` | Container for language change select menu | -| `#menuOptionsSelectMenuLang` | Language select menu | -| `#DownloadProgress` | Download progress container | -| `#bottomSectionContainer` | Bottom section container | -| `#miniDownloadContainer` | Container for mini download | +| #ID | Description | +| ------------------------------------ | --------------------------------------------------------------- | +| `#miniDialogContainer` | Main container of MiniDialog | +| `#miniDialogContainerTop` | Affects only top section of MiniDialog | +| `#miniDialogButtonClose` | Close button (SVG) of MiniDialog | +| `#miniDialogContent` | MiniDialog content | +| `#rightBarContainer` | Main container of RightBar | +| `#rightBarContent` | RightBar content | +| `#rightBarButtonDiscord` | Discord button on the RightBar | +| `#rightBarButtonGithub` | Github button on the RightBar | +| `#playButton` | Main container for whole launch buttons section | +| `#serverControls` | Container of "play on grasscutter" checkbox | +| `#enableGC` | "play on grasscutter" checkbox | +| `#ip` | Server ip input if play on grasscutter is enabled | +| `#port` | Server port input if play on grasscutter is enabled | +| `#httpsEnable` | "Enable https" checkbox if play on grasscutter is enabled | +| `#officialPlay` | Launch button | +| `#serverLaunch` | Launch server button | +| `#serverlaunchIcon` | Icon (SVG) of server launch button | +| `#serverConfigContainer` | Main container of server configuration section | +| `#serverLaunchContainer` | Main container of launch buttons (includes launch server) | +| `#topBarContainer` | Main container of launcher TopBar (minimize, exit, settings...) | +| `#title` | Title of the TopBar | +| `#version` | Version of the launcher in TopBar | +| `#topBarButtonContainer` | Container of launcher TopBar buttons only | +| `#closeBtn` | Exit launcher button | +| `#minBtn` | Minimize launcher button | +| `#settingsBtn` | Settings button | +| `#downloadsBtn` | Downloads button (grasscutter resources, grasscutter...) | +| `#newsContainer` | Main container of the news section | +| `#newsTabsContainer` | Container for news tabs | +| `#commits` | News tabs container commits button | +| `#latest_version` | News tabs for latest version button | +| `#newsContent` | Content section of news container | +| `#newsCommitsTable` | Commits table of news section | +| `#downloadMenuContainerGCStable` | Grasscutter stable update container | +| `#downloadMenuLabelGCStable` | Label for stable update button | +| `#downloadMenuButtonGCStable` | Button container for stable update button | +| `#grasscutterStableBtn` | "Update grasscutter stable" button | +| `#downloadMenuContainerGCDev` | Grasscutter development update container | +| `#downloadMenuLabelGCDev` | Label for latest update button | +| `#downloadMenuButtonGCDev` | Button container for latest update button | +| `grasscutterLatestBtn` | "Update grasscutter latest" button | +| `#downloadMenuContainerGCStableData` | Grasscutter stable data update container | +| `#downloadMenuLabelGCStableData` | Label for stable data update | +| `#downloadMenuButtonGCStableData` | Button container for stable data update button | +| `#grasscutterStableRepo` | "Update grasscutter stable data" button | +| `#downloadMenuContainerGCDevData` | Grasscutter latest data update container | +| `#downloadMenuLabelGCDevData` | Label for latest data update | +| `#downloadMenuButtonGCDevData` | Button container for latest data update button | +| `#grasscutterDevRepo` | "Update grasscutter latest data" button | +| `#downloadMenuContainerResources` | Container for grasscutter resources download | +| `#downloadMenuLabelResources` | label for resources download | +| `#downloadMenuButtonResources` | Button container for resources download button | +| `#resourcesBtn` | "Download grasscutter resources" button | +| `#menuContainer` | Generic Popup modal like menu container | +| `#menuContainerTop` | Top section of menu container | +| `#menuHeading` | Menu title | +| `#menuButtonCloseContainer` | Container for menu close button | +| `#menuButtonCloseIcon` | Menu close icon (SVG) | +| `#menuContent` | Content section of the menu | +| `#menuOptionsContainerGameExec` | Container for game executable option section | +| `#menuOptionsLabelGameExec` | Label for game executable option | +| `#menuOptionsDirGameExec` | Set game executable file browser | +| `#menuOptionsContainerGCJar` | Container for grasscutter jar option | +| `#menuOptionsLabelGCJar` | Label for grasscutter jar option | +| `#menuOptionsDirGCJar` | Set grasscutter jar file browser | +| `#menuOptionsContainerToggleEnc` | Container for toggle encryption option | +| `#menuOptionsLabelToggleEnc` | Label for toggle encryption option | +| `#menuOptionsButtonToggleEnc` | Toggle encryption button container | +| `#toggleEnc` | Toggle encryption button | +| `#menuOptionsContainerGCWGame` | Container for "grasscutter with game" option | +| `#menuOptionsLabelGCWDame` | Label for "grasscutter with game" option | +| `#menuOptionsCheckboxGCWGame` | Container for "grasscutter with game" option checkbox | +| `#gcWithGame` | Grasscutter with game checkbox | +| `#menuOptionsContainerThemes` | Container for themes section | +| `#menuOptionsLabelThemes` | Label for set themes option | +| `#menuOptionsSelectThemes` | Container for themes select menu | +| `#menuOptionsSelectMenuThemes` | Set theme select menu | +| `#menuOptionsContainerJavaPath` | Container for Java Path option | +| `#menuOptionsLabelJavaPath` | Label for Java path option | +| `#menuOptionsDirJavaPath` | Container for java path file browser | +| `#menuOptionsContainerBG` | Container for Background option | +| `#menuOptionsLabelBG` | Label for background option | +| `#menuOptionsDirBG` | Container for background url/local path option | +| `#menuOptionsContainerLang` | Container for language change option | +| `#menuOptionsLabelLang` | Label for language change option | +| `#menuOptionsSelectLang` | Container for language change select menu | +| `#menuOptionsSelectMenuLang` | Language select menu | +| `#DownloadProgress` | Download progress container | +| `#bottomSectionContainer` | Bottom section container | +| `#miniDownloadContainer` | Container for mini download | ## Classes + This is not full list of all classes, rather its list of classes for commonly used components that can not be accessed using element id system. -| .Class | Description | -|-----------------------------|---------------------------------------------------------| -| `.BigButton` | Class for all buttons | -| `.BigButtonText` | Text inside a button | | -| `.Checkbox` | Checkbox container | -| `.CheckboxDisplay` | Content of checkbox | -| `.DirInput` | Container for DirInput | -| `.FileSelectIcon` | Icon of DirInput | -| `.DownloadList` | List of all downloads | -| `.DownloadSection` | Container for each download | -| `.DownloadTitle` | Contains file download path and current status | -| `.DownloadPath` | Path of a download | -| `.DownloadStatus` | Status of a download | -| `.DownloadSectionInner` | Contains progressbar of the download section | -| `.HelpSection` | Container for help "?" circle button | -| `.HelpButton` | HelpButton itself | -| `.HelpContents` | Content of help button once expanded | -| `.MainProgressBarWrapper` | Container for MainProgressBar | -| `.ProgressBar` | ProgressBar (creativity left the brain) | -| `.InnerProgress` | ProgressBar percentage | -| `.MainProgressText` | Text for MainProgressBar | -| `.ProgressBarWrapper` | Container for ProgressBar | -| `.DownloadControls` | DownloadControls of ProgressBar | -| `.downloadStop` | Container for download stop icon (SVG) | -| `.ProgressText` | Text of the ProgressBar display current download status | -| `.TextInputWrapper` | Container for TextInput | -| `.TextClear` | Container for clear input content button | -| `.TextInputClear` | TextInput clear button icon (SVG) | -| `.Divider` | Container for line dividers | -| `.DividerLine` | Divider line itself | -| `.CommitAuthor` | Author of a commit | -| `.CommitMessage` | Message of a commit | \ No newline at end of file +| .Class | Description | +| ------------------------- | ------------------------------------------------------- | --- | +| `.BigButton` | Class for all buttons | +| `.BigButtonText` | Text inside a button | | +| `.Checkbox` | Checkbox container | +| `.CheckboxDisplay` | Content of checkbox | +| `.DirInput` | Container for DirInput | +| `.FileSelectIcon` | Icon of DirInput | +| `.DownloadList` | List of all downloads | +| `.DownloadSection` | Container for each download | +| `.DownloadTitle` | Contains file download path and current status | +| `.DownloadPath` | Path of a download | +| `.DownloadStatus` | Status of a download | +| `.DownloadSectionInner` | Contains progressbar of the download section | +| `.HelpSection` | Container for help "?" circle button | +| `.HelpButton` | HelpButton itself | +| `.HelpContents` | Content of help button once expanded | +| `.MainProgressBarWrapper` | Container for MainProgressBar | +| `.ProgressBar` | ProgressBar (creativity left the brain) | +| `.InnerProgress` | ProgressBar percentage | +| `.MainProgressText` | Text for MainProgressBar | +| `.ProgressBarWrapper` | Container for ProgressBar | +| `.DownloadControls` | DownloadControls of ProgressBar | +| `.downloadStop` | Container for download stop icon (SVG) | +| `.ProgressText` | Text of the ProgressBar display current download status | +| `.TextInputWrapper` | Container for TextInput | +| `.TextClear` | Container for clear input content button | +| `.TextInputClear` | TextInput clear button icon (SVG) | +| `.Divider` | Container for line dividers | +| `.DividerLine` | Divider line itself | +| `.CommitAuthor` | Author of a commit | +| `.CommitMessage` | Message of a commit | diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 7e0a38b..1ba8d22 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -1,15 +1,19 @@ # Troubleshooting + A guide dedicated for trying to troubleshoot Cultivation. ## The launcher doesn't appear to open. + Try running the launcher with **administrative privileges**.\ If this fixes your issue, you can force enable it in the **Compatability**\ tab for the launcher's executable. ## Unable to play on `localhost`. + Make sure your server is running with **encryption disabled** and `useInRouting` to **false**.\ Additionally, make sure Cultivation **is set to not use HTTPS**. ## "I can't do anything requiring the internet after closing Cultivation!" + You probably didn't close Cultivation properly.\ -Go to your *Windows Settings*, then *Network*, then *Proxy*, then disable it. \ No newline at end of file +Go to your _Windows Settings_, then _Network_, then _Proxy_, then disable it. diff --git a/public/index.html b/public/index.html index 030b8e7..900bdf1 100644 --- a/public/index.html +++ b/public/index.html @@ -5,10 +5,7 @@ - + Cultivation diff --git a/src-tauri/lang/de.json b/src-tauri/lang/de.json index 85b58b1..cbce7f5 100644 --- a/src-tauri/lang/de.json +++ b/src-tauri/lang/de.json @@ -1,61 +1,61 @@ -{ - "lang_name": "Deutsch", - "main": { - "title": "Cultivation", - "launch_button": "Starten", - "gc_enable": "Über Grasscutter verbinden", - "https_enable": "HTTPS nutzen", - "ip_placeholder": "Server Adresse...", - "port_placeholder": "Port...", - "files_downloading": "Herunterladen von Dateien: ", - "files_extracting": "Extrahieren von Dateien: " - }, - "options": { - "enabled": "Aktiviert", - "disabled": "Deaktiviert", - "game_executable": "Spiel Datei auswählen", - "grasscutter_jar": "Grasscuter JAR auswählen", - "toggle_encryption": "Verschlüsselung umschalten", - "java_path": "Benutzerdefinierten Java Pfad setzen", - "grasscutter_with_game": "Grasscutter automatisch mit dem Spiel starten", - "language": "Sprache auswählen", - "background": "Benutzerdefinierten Hintergrund festlegen (link oder bild)", - "theme": "Theme auswählen" - }, - "downloads": { - "grasscutter_stable_data": "Stabile Grasscutter Daten herunterladen", - "grasscutter_latest_data": "Aktuellste Grasscutter Daten herunterladen", - "grasscutter_stable_data_update": "Stabile Grasscutter Daten aktualisieren", - "grasscutter_latest_data_update": "Aktuellste Grasscutter Daten aktualisieren", - "grasscutter_stable": "Stabile Grasscutter Version herunterladen", - "grasscutter_latest": "Aktuellste Grasscutter Version herunterladen", - "grasscutter_stable_update": "Stabile Grasscutter Version aktualisieren", - "grasscutter_latest_update": "Aktuellste Grasscutter Version aktualisieren", - "resources": "Grasscutter Ressourcen herunterladen" - }, - "download_status": { - "downloading": "Lädt herunter", - "extracting": "Extrahiert", - "error": "Fehler", - "finished": "Fertig", - "stopped": "Gestoppt" - }, - "components": { - "select_file": "Datei oder Ordner auswählen...", - "select_folder": "Ordner auswählen...", - "download": "Herunterladen" - }, - "news": { - "latest_commits": "Letzte Commits", - "latest_version": "Letzte Version" - }, - "help": { - "port_help_text": "Vergewissern Sie sich, dass es sich um den Port des Dispatch-Servers handelt, nicht um den Port des Spiel-Servers. Dieser ist fast immer '443'.", - "game_help_text": "Sie müssen keine separate Kopie verwenden, um mit Grasscutter zu spielen. Dies ist entweder für ein Downgrade auf die Version 2.6 oder wenn Sie das Spiel nicht installiert haben.", - "gc_stable_jar": "Laden Sie den aktuellen stabilen Grasscutter-Build herunter, der eine Jar-Datei und Datendateien enthält.", - "gc_dev_jar": "Laden Sie die neueste Grasscutter-Entwicklungsversion herunter, welche eine Jar-Datei und Datendateien enthält.", - "gc_stable_data": "Laden Sie die stabilen Grasscutter Daten herunter, welche keine Jar-Datei enthalten. Dies ist nützlich zum Aktualisieren.", - "gc_dev_data": "Laden Sie die neuesten Grasscutter-Entwicklungsdateien herunter, welche keine Jar-Datei enthält. Dies ist nützlich zum Aktualisieren.", - "resources": "Diese werden auch benötigt, um einen Grasscutter-Server auszuführen. Diese Schaltfläche ist grau, wenn Sie einen bestehenden Ressourcenordner mit Inhalten haben" - } - } \ No newline at end of file +{ + "lang_name": "Deutsch", + "main": { + "title": "Cultivation", + "launch_button": "Starten", + "gc_enable": "Über Grasscutter verbinden", + "https_enable": "HTTPS nutzen", + "ip_placeholder": "Server Adresse...", + "port_placeholder": "Port...", + "files_downloading": "Herunterladen von Dateien: ", + "files_extracting": "Extrahieren von Dateien: " + }, + "options": { + "enabled": "Aktiviert", + "disabled": "Deaktiviert", + "game_executable": "Spiel Datei auswählen", + "grasscutter_jar": "Grasscuter JAR auswählen", + "toggle_encryption": "Verschlüsselung umschalten", + "java_path": "Benutzerdefinierten Java Pfad setzen", + "grasscutter_with_game": "Grasscutter automatisch mit dem Spiel starten", + "language": "Sprache auswählen", + "background": "Benutzerdefinierten Hintergrund festlegen (link oder bild)", + "theme": "Theme auswählen" + }, + "downloads": { + "grasscutter_stable_data": "Stabile Grasscutter Daten herunterladen", + "grasscutter_latest_data": "Aktuellste Grasscutter Daten herunterladen", + "grasscutter_stable_data_update": "Stabile Grasscutter Daten aktualisieren", + "grasscutter_latest_data_update": "Aktuellste Grasscutter Daten aktualisieren", + "grasscutter_stable": "Stabile Grasscutter Version herunterladen", + "grasscutter_latest": "Aktuellste Grasscutter Version herunterladen", + "grasscutter_stable_update": "Stabile Grasscutter Version aktualisieren", + "grasscutter_latest_update": "Aktuellste Grasscutter Version aktualisieren", + "resources": "Grasscutter Ressourcen herunterladen" + }, + "download_status": { + "downloading": "Lädt herunter", + "extracting": "Extrahiert", + "error": "Fehler", + "finished": "Fertig", + "stopped": "Gestoppt" + }, + "components": { + "select_file": "Datei oder Ordner auswählen...", + "select_folder": "Ordner auswählen...", + "download": "Herunterladen" + }, + "news": { + "latest_commits": "Letzte Commits", + "latest_version": "Letzte Version" + }, + "help": { + "port_help_text": "Vergewissern Sie sich, dass es sich um den Port des Dispatch-Servers handelt, nicht um den Port des Spiel-Servers. Dieser ist fast immer '443'.", + "game_help_text": "Sie müssen keine separate Kopie verwenden, um mit Grasscutter zu spielen. Dies ist entweder für ein Downgrade auf die Version 2.6 oder wenn Sie das Spiel nicht installiert haben.", + "gc_stable_jar": "Laden Sie den aktuellen stabilen Grasscutter-Build herunter, der eine Jar-Datei und Datendateien enthält.", + "gc_dev_jar": "Laden Sie die neueste Grasscutter-Entwicklungsversion herunter, welche eine Jar-Datei und Datendateien enthält.", + "gc_stable_data": "Laden Sie die stabilen Grasscutter Daten herunter, welche keine Jar-Datei enthalten. Dies ist nützlich zum Aktualisieren.", + "gc_dev_data": "Laden Sie die neuesten Grasscutter-Entwicklungsdateien herunter, welche keine Jar-Datei enthält. Dies ist nützlich zum Aktualisieren.", + "resources": "Diese werden auch benötigt, um einen Grasscutter-Server auszuführen. Diese Schaltfläche ist grau, wenn Sie einen bestehenden Ressourcenordner mit Inhalten haben" + } +} diff --git a/src-tauri/lang/en.json b/src-tauri/lang/en.json index d97ad77..4255dbd 100644 --- a/src-tauri/lang/en.json +++ b/src-tauri/lang/en.json @@ -69,4 +69,4 @@ "akebi": "Set Akebi Executable", "migoto": "Set 3dMigoto Executable" } -} \ No newline at end of file +} diff --git a/src-tauri/lang/es.json b/src-tauri/lang/es.json index e75fe69..86e606d 100644 --- a/src-tauri/lang/es.json +++ b/src-tauri/lang/es.json @@ -66,4 +66,4 @@ "swag": { "akebi": "Establecer el ejecutable de Akebi" } -} \ No newline at end of file +} diff --git a/src-tauri/lang/id.json b/src-tauri/lang/id.json index 25afcdf..faafe47 100644 --- a/src-tauri/lang/id.json +++ b/src-tauri/lang/id.json @@ -18,7 +18,7 @@ "background": "Atur Kustom Latar Belakang (link atau gambar file)", "theme": "Atur Tema" }, - "downloads": { + "downloads": { "grasscutter_stable_data": "Sedang Mendownload Grasscutter Versi Stabil", "grasscutter_latest_data": "Sedang Mendownload Grasscutter Data Terbaru", "grasscutter_stable_data_update": "Memperbaharui Grasscutter Data Stabil", @@ -54,4 +54,4 @@ "gc_dev_data": "Unduh file data Grasscutter Development saat ini, dimana Tidak Ada JAR file. Ini Berguna Untuk memperbarui.", "resources": "Ini juga diperlukan untuk menjalankan server Grasscutter. Tombol ini akan berwarna abu-abu jika Anda memiliki folder Resource yang ada dengan File di dalamnya" } -} \ No newline at end of file +} diff --git a/src-tauri/lang/ru.json b/src-tauri/lang/ru.json index 6e21a89..2dbb2ad 100644 --- a/src-tauri/lang/ru.json +++ b/src-tauri/lang/ru.json @@ -1,61 +1,61 @@ -{ - "lang_name": "Русский", - "main": { - "title": "Cultivation", - "launch_button": "Запустить", - "gc_enable": "Подключиться с Grasscutter", - "https_enable": "Исп. HTTPS", - "ip_placeholder": "Айпи адрес...", - "port_placeholder": "Порт...", - "files_downloading": "Файлов скачано: ", - "files_extracting": "Извлечено файлов: " - }, - "options": { - "enabled": "Включено", - "disabled": "Выключено", - "game_executable": "Установить исполняемый файл игры", - "grasscutter_jar": "Установить Grasscutter JAR", - "toggle_encryption": "Переключить шифрование", - "java_path": "Установить пользовательский путь Java", - "grasscutter_with_game": "Автоматически запускать Grasscutter вместе с игрой", - "language": "Установить язык", - "background": "Установить свой фон (ссылка или файл)", - "theme": "Установить тему" - }, - "downloads": { - "grasscutter_stable_data": "Скачать стабильные данные Grasscutter", - "grasscutter_latest_data": "Скачать последние данные Grasscutter", - "grasscutter_stable_data_update": "Обновить стабильные данные Grasscutter", - "grasscutter_latest_data_update": "Обновить последние данные Grasscutter", - "grasscutter_stable": "Скачать стабильную версию Grasscutter", - "grasscutter_latest": "Скачать последнюю версию Grasscutter", - "grasscutter_stable_update": "Обновить стабильную версию Grasscutter", - "grasscutter_latest_update": "Обновить последнюю версию Grasscutter", - "resources": "Скачать ресурсы Grasscutter" - }, - "download_status": { - "downloading": "Скачивание", - "extracting": "Извлечение", - "error": "Ошибка", - "finished": "Закончено", - "stopped": "Остановлено" - }, - "components": { - "select_file": "Выберите файл или папку...", - "select_folder": "Выберите папку...", - "download": "Скачать" - }, - "news": { - "latest_commits": "Последние коммиты", - "latest_version": "Последняя версия" - }, - "help": { - "port_help_text": "Убедитесь, что это порт Dispatch-сервера, не порт игрового сервера. Обычно это '443'.", - "game_help_text": "Вам не нужно устанавливать еще одну копию, что бы играть с Grascutter. Это нужно или для версии 2.6, или если у Вас не установлена игра.", - "gc_stable_jar": "Скачать последнюю стабильную версию Grasscutter, которая содержит jar файл и данные.", - "gc_dev_jar": "Скачать последнюю версию для разработки Grasscutter, которая содержит jar файл и данные.", - "gc_stable_data": "Скачать стабильные данные Grasscutter, в которой нету jar файла. Это полезно для обновления.", - "gc_dev_data": "Скачать последнюю версию для разработки Grasscutter, в которой нету jar файла. Это полезно для обновления.", - "resources": "Это необходимо для запуска сервера Grasscutter. Эта кнопка будет серой, если у Вас уже есть не пустая папка с ресурсами." - } -} \ No newline at end of file +{ + "lang_name": "Русский", + "main": { + "title": "Cultivation", + "launch_button": "Запустить", + "gc_enable": "Подключиться с Grasscutter", + "https_enable": "Исп. HTTPS", + "ip_placeholder": "Айпи адрес...", + "port_placeholder": "Порт...", + "files_downloading": "Файлов скачано: ", + "files_extracting": "Извлечено файлов: " + }, + "options": { + "enabled": "Включено", + "disabled": "Выключено", + "game_executable": "Установить исполняемый файл игры", + "grasscutter_jar": "Установить Grasscutter JAR", + "toggle_encryption": "Переключить шифрование", + "java_path": "Установить пользовательский путь Java", + "grasscutter_with_game": "Автоматически запускать Grasscutter вместе с игрой", + "language": "Установить язык", + "background": "Установить свой фон (ссылка или файл)", + "theme": "Установить тему" + }, + "downloads": { + "grasscutter_stable_data": "Скачать стабильные данные Grasscutter", + "grasscutter_latest_data": "Скачать последние данные Grasscutter", + "grasscutter_stable_data_update": "Обновить стабильные данные Grasscutter", + "grasscutter_latest_data_update": "Обновить последние данные Grasscutter", + "grasscutter_stable": "Скачать стабильную версию Grasscutter", + "grasscutter_latest": "Скачать последнюю версию Grasscutter", + "grasscutter_stable_update": "Обновить стабильную версию Grasscutter", + "grasscutter_latest_update": "Обновить последнюю версию Grasscutter", + "resources": "Скачать ресурсы Grasscutter" + }, + "download_status": { + "downloading": "Скачивание", + "extracting": "Извлечение", + "error": "Ошибка", + "finished": "Закончено", + "stopped": "Остановлено" + }, + "components": { + "select_file": "Выберите файл или папку...", + "select_folder": "Выберите папку...", + "download": "Скачать" + }, + "news": { + "latest_commits": "Последние коммиты", + "latest_version": "Последняя версия" + }, + "help": { + "port_help_text": "Убедитесь, что это порт Dispatch-сервера, не порт игрового сервера. Обычно это '443'.", + "game_help_text": "Вам не нужно устанавливать еще одну копию, что бы играть с Grascutter. Это нужно или для версии 2.6, или если у Вас не установлена игра.", + "gc_stable_jar": "Скачать последнюю стабильную версию Grasscutter, которая содержит jar файл и данные.", + "gc_dev_jar": "Скачать последнюю версию для разработки Grasscutter, которая содержит jar файл и данные.", + "gc_stable_data": "Скачать стабильные данные Grasscutter, в которой нету jar файла. Это полезно для обновления.", + "gc_dev_data": "Скачать последнюю версию для разработки Grasscutter, в которой нету jar файла. Это полезно для обновления.", + "resources": "Это необходимо для запуска сервера Grasscutter. Эта кнопка будет серой, если у Вас уже есть не пустая папка с ресурсами." + } +} diff --git a/src-tauri/lang/vi.json b/src-tauri/lang/vi.json index 6b1d3cd..443250b 100644 --- a/src-tauri/lang/vi.json +++ b/src-tauri/lang/vi.json @@ -58,4 +58,4 @@ "gc_dev_data": "Tải xuống bản phát triển mới nhất các tệp dữ liệu của Grasscutter, không bao gồm file jar. Phù hợp khi cập nhật.", "resources": "Chúng được yêu cầu để chạy máy chủ Grasscutter. Nút này sẽ có màu xám nếu bạn có một thư mục tài nguyên có nội dung bên trong" } -} \ No newline at end of file +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 4bf076b..e5bc109 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -12,20 +12,12 @@ "tauri": { "allowlist": { "fs": { - "scope": [ - "$DATA", - "$DATA/cultivation", - "$DATA/cultivation/*" - ] + "scope": ["$DATA", "$DATA/cultivation", "$DATA/cultivation/*"] }, "protocol": { "all": true, "asset": true, - "assetScope": [ - "$DATA", - "$DATA/cultivation", - "$DATA/cultivation/*" - ] + "assetScope": ["$DATA", "$DATA/cultivation", "$DATA/cultivation/*"] }, "all": true }, @@ -37,13 +29,7 @@ "depends": [] }, "externalBin": [], - "icon": [ - "icons/32x32.png", - "icons/128x128.png", - "icons/128x128@2x.png", - "icons/icon.icns", - "icons/icon.ico" - ], + "icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"], "identifier": "io.grasscutter", "shortDescription": "A game launcher.", "longDescription": "A launcher for a certain anime game that proxies all related game traffic to external servers.", @@ -54,11 +40,7 @@ "providerShortName": null, "signingIdentity": null }, - "resources": [ - "lang/*.json", - "keys/*", - "./mhycrypto.dll" - ], + "resources": ["lang/*.json", "keys/*", "./mhycrypto.dll"], "targets": "all", "windows": { "allowDowngrades": false, @@ -93,4 +75,4 @@ } ] } -} \ No newline at end of file +} diff --git a/src/index.css b/src/index.css index ec7b949..f7b32d2 100644 --- a/src/index.css +++ b/src/index.css @@ -1,13 +1,11 @@ body { margin: 0; - font-family: 'MiHoYo_SDK_Web', 'Helvetica Neue', BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', - sans-serif; + font-family: 'MiHoYo_SDK_Web', 'Helvetica Neue', BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', + 'Cantarell', 'Fira Sans', 'Droid Sans', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } diff --git a/src/index.tsx b/src/index.tsx index e2b5cab..f2aff33 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,23 +7,15 @@ import Debug from './ui/Debug' import { getConfigOption } from './utils/configuration' -const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement -) +const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement) -let isDebug = false; +let isDebug = false -(async() => { +;async () => { isDebug = await getConfigOption('debug_enabled') -}) +} -root.render( - - { - isDebug ? : - } - -) +root.render({isDebug ? : }) import reportWebVitals from './utils/reportWebVitals' -isDebug && reportWebVitals(console.log) \ No newline at end of file +isDebug && reportWebVitals(console.log) diff --git a/src/ui/App.css b/src/ui/App.css index 99074c7..d8eddae 100644 --- a/src/ui/App.css +++ b/src/ui/App.css @@ -22,7 +22,8 @@ select:focus { border-bottom-color: #ffd326; } -#root, .App { +#root, +.App { height: 100%; } @@ -64,8 +65,8 @@ select:focus { } .arrow-down { - width: 0; - height: 0; + width: 0; + height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-top: 50px solid transparent; @@ -82,28 +83,28 @@ select:focus { .BottomSection { position: absolute; - bottom: 0%; - left: 50%; - transform: translate(-50%, 0%); + bottom: 0%; + left: 50%; + transform: translate(-50%, 0%); - width: 100%; - height: 160px; + width: 100%; + height: 160px; backdrop-filter: blur(10px); box-shadow: inset 0px 5px 12px -3px rgb(50 50 50 / 75%); - margin: 0; - padding: 0; + margin: 0; + padding: 0; } -@media(max-height: 580px) { - .BottomSection { - height: 150px; - } +@media (max-height: 580px) { + .BottomSection { + height: 150px; + } } -@media(max-height: 500px) { - .BottomSection { - height: 140px; - } -} \ No newline at end of file +@media (max-height: 500px) { + .BottomSection { + height: 140px; + } +} diff --git a/src/ui/App.tsx b/src/ui/App.tsx index 6237880..da2ce7d 100644 --- a/src/ui/App.tsx +++ b/src/ui/App.tsx @@ -25,16 +25,16 @@ import { getTheme, loadTheme } from '../utils/themes' import { unpatchGame } from '../utils/metadata' interface IProps { - [key: string]: never; + [key: string]: never } interface IState { - isDownloading: boolean; - optionsOpen: boolean; - miniDownloadsOpen: boolean; - downloadsOpen: boolean; - gameDownloadsOpen: boolean; - bgFile: string; + isDownloading: boolean + optionsOpen: boolean + miniDownloadsOpen: boolean + downloadsOpen: boolean + gameDownloadsOpen: boolean + bgFile: string } const DEFAULT_BG = 'https://api.grasscutter.io/cultivation/bgfile' @@ -57,7 +57,7 @@ class App extends React.Component { console.log(payload) }) - listen('jar_extracted', ({ payload }: { payload: string}) => { + listen('jar_extracted', ({ payload }: { payload: string }) => { setConfigOption('grasscutter_path', payload) }) @@ -69,9 +69,11 @@ class App extends React.Component { const unpatched = await unpatchGame() console.log(`unpatched game? ${unpatched}`) - + if (!unpatched) { - alert(`Could not unpatch game! (You should be able to find your metadata backup in ${await dataDir()}\\cultivation\\)`) + alert( + `Could not unpatch game! (You should be able to find your metadata backup in ${await dataDir()}\\cultivation\\)` + ) } } }) @@ -108,45 +110,55 @@ class App extends React.Component { // Get custom bg AFTER theme is loaded !! important !! const custom_bg = await getConfigOption('customBackground') - if(!custom_bg || !/png|jpg|jpeg$/.test(custom_bg)) { - if(game_path) { + if (!custom_bg || !/png|jpg|jpeg$/.test(custom_bg)) { + if (game_path) { // Get the bg by invoking, then set the background to that bg. const bgLoc: string = await invoke('get_bg_file', { bgPath: root_path, - appdata: await dataDir() + appdata: await dataDir(), }) - bgLoc && this.setState({ - bgFile: bgLoc - }, this.forceUpdate) + bgLoc && + this.setState( + { + bgFile: bgLoc, + }, + this.forceUpdate + ) } } else { const isUrl = /^http(s)?:\/\//gm.test(custom_bg) if (!isUrl) { const isValid = await invoke('dir_exists', { - path: custom_bg + path: custom_bg, }) - this.setState({ - bgFile: isValid ? convertFileSrc(custom_bg) : DEFAULT_BG - }, this.forceUpdate) + this.setState( + { + bgFile: isValid ? convertFileSrc(custom_bg) : DEFAULT_BG, + }, + this.forceUpdate + ) } else { // Check if URL returns a valid image. const isValid = await invoke('valid_url', { - url: custom_bg + url: custom_bg, }) - this.setState({ - bgFile: isValid ? custom_bg : DEFAULT_BG - }, this.forceUpdate) + this.setState( + { + bgFile: isValid ? custom_bg : DEFAULT_BG, + }, + this.forceUpdate + ) } } if (!cert_generated) { // Generate the certificate await invoke('generate_ca_files', { - path: await dataDir() + 'cultivation' + path: (await dataDir()) + 'cultivation', }) await setConfigOption('cert_generated', true) @@ -155,18 +167,23 @@ class App extends React.Component { // Period check to only show progress bar when downloading files setInterval(() => { this.setState({ - isDownloading: downloadHandler.getDownloads().filter(d => d.status !== 'finished')?.length > 0 + isDownloading: downloadHandler.getDownloads().filter((d) => d.status !== 'finished')?.length > 0, }) }, 1000) } render() { return ( -
+
{ this.setState({ optionsOpen: !this.state.optionsOpen }) @@ -199,10 +216,7 @@ class App extends React.Component { { // Download menu this.state.downloadsOpen ? ( - this.setState({ downloadsOpen: false })} - /> + this.setState({ downloadsOpen: false })} /> ) : null } @@ -219,22 +233,18 @@ class App extends React.Component { { // Game downloads menu this.state.gameDownloadsOpen ? ( - this.setState({ gameDownloadsOpen: false })} - /> + this.setState({ gameDownloadsOpen: false })} /> ) : null }
-
this.setState({ miniDownloadsOpen: !this.state.miniDownloadsOpen })} > - { this.state.isDownloading ? - - : null } + {this.state.isDownloading ? : null}
diff --git a/src/ui/Debug.tsx b/src/ui/Debug.tsx index 4846541..11d78de 100644 --- a/src/ui/Debug.tsx +++ b/src/ui/Debug.tsx @@ -3,8 +3,8 @@ import './App.css' import TopBar from './components/TopBar' -import {invoke} from '@tauri-apps/api/tauri' -import {dataDir} from '@tauri-apps/api/path' +import { invoke } from '@tauri-apps/api/tauri' +import { dataDir } from '@tauri-apps/api/path' import TextInput from './components/common/TextInput' let proxyAddress = '' @@ -15,7 +15,7 @@ async function setProxyAddress(address: string) { } async function startProxy() { - await invoke('connect', { port: 2222, certificatePath: await dataDir() + '\\cultivation\\ca' }) + await invoke('connect', { port: 2222, certificatePath: (await dataDir()) + '\\cultivation\\ca' }) await invoke('open_in_browser', { url: 'https://hoyoverse.com' }) } @@ -24,14 +24,14 @@ async function stopProxy() { } async function generateCertificates() { - await invoke('generate_ca_files', { path: await dataDir() + '\\cultivation' }) + await invoke('generate_ca_files', { path: (await dataDir()) + '\\cultivation' }) } async function generateInfo() { console.log({ - certificatePath: await dataDir() + '\\cultivation\\ca', + certificatePath: (await dataDir()) + '\\cultivation\\ca', isAdmin: await invoke('is_elevated'), - connectingTo: proxyAddress + connectingTo: proxyAddress, }) alert('check your dev console and send that in #cultivation') } @@ -40,7 +40,7 @@ function none() { alert('none') } -class Debug extends React.Component{ +class Debug extends React.Component { render() { return (
@@ -55,4 +55,4 @@ class Debug extends React.Component{ } } -export default Debug \ No newline at end of file +export default Debug diff --git a/src/ui/components/MiniDialog.css b/src/ui/components/MiniDialog.css index 1a7e0ed..bd47fc2 100644 --- a/src/ui/components/MiniDialog.css +++ b/src/ui/components/MiniDialog.css @@ -1,7 +1,7 @@ .MiniDialog { position: fixed; z-index: 99; - + /* Len and width */ height: 30%; width: 30%; @@ -32,4 +32,4 @@ .MiniDialog .ProgressText { color: #000; -} \ No newline at end of file +} diff --git a/src/ui/components/MiniDialog.tsx b/src/ui/components/MiniDialog.tsx index e7c3bfc..c27089d 100644 --- a/src/ui/components/MiniDialog.tsx +++ b/src/ui/components/MiniDialog.tsx @@ -4,10 +4,10 @@ import Close from '../../resources/icons/close.svg' import './MiniDialog.css' interface IProps { - children: React.ReactNode[] | React.ReactNode; - title?: string; - closeable?: boolean; - closeFn: () => void; + children: React.ReactNode[] | React.ReactNode + title?: string + closeable?: boolean + closeFn: () => void } export default class MiniDialog extends React.Component { @@ -19,7 +19,7 @@ export default class MiniDialog extends React.Component { document.addEventListener('mousedown', (evt) => { const tgt = evt.target as HTMLElement const isInside = tgt.closest('.MiniDialog') !== null - + if (!isInside) { this.props.closeFn() } @@ -33,13 +33,12 @@ export default class MiniDialog extends React.Component { render() { return (
- { - this.props.closeable !== undefined && this.props.closeable ? -
- {this.props?.title} - -
: null - } + {this.props.closeable !== undefined && this.props.closeable ? ( +
+ {this.props?.title} + +
+ ) : null}
{this.props.children} @@ -47,4 +46,4 @@ export default class MiniDialog extends React.Component {
) } -} \ No newline at end of file +} diff --git a/src/ui/components/RightBar.css b/src/ui/components/RightBar.css index dd0218b..608064f 100644 --- a/src/ui/components/RightBar.css +++ b/src/ui/components/RightBar.css @@ -2,7 +2,7 @@ position: absolute; transform: translate(0%, 0%); - display:flex; + display: flex; flex-direction: column; align-items: center; justify-content: flex-start; @@ -36,14 +36,14 @@ filter: invert(75%) sepia(0%) saturate(100%) hue-rotate(0deg) brightness(100%) contrast(100%); } -@media(max-height: 580px) { - .RightBar { - height: calc(100vh - 180px); - } +@media (max-height: 580px) { + .RightBar { + height: calc(100vh - 180px); + } } -@media(max-height: 500px) { - .RightBar { - height: calc(100vh - 170px); - } -} \ No newline at end of file +@media (max-height: 500px) { + .RightBar { + height: calc(100vh - 170px); + } +} diff --git a/src/ui/components/RightBar.tsx b/src/ui/components/RightBar.tsx index f3f1ff7..456fde4 100644 --- a/src/ui/components/RightBar.tsx +++ b/src/ui/components/RightBar.tsx @@ -1,8 +1,8 @@ import { invoke } from '@tauri-apps/api' import React from 'react' -import Discord from '../../resources/icons/discord.svg' -import Github from '../../resources/icons/github.svg' +import Discord from '../../resources/icons/discord.svg' +import Github from '../../resources/icons/github.svg' import './RightBar.css' @@ -28,4 +28,4 @@ export default class RightBar extends React.Component {
) } -} \ No newline at end of file +} diff --git a/src/ui/components/ServerLaunchSection.css b/src/ui/components/ServerLaunchSection.css index be805ae..8b6d0c0 100644 --- a/src/ui/components/ServerLaunchSection.css +++ b/src/ui/components/ServerLaunchSection.css @@ -109,17 +109,17 @@ } @media (max-width: 1040px) { - #playButton { - right: 5%; - } + #playButton { + right: 5%; + } } @media (max-width: 870px) { - #playButton { - min-width: 235px; - } + #playButton { + min-width: 235px; + } - #officialPlay { - width: 40%; - } + #officialPlay { + width: 40%; + } } diff --git a/src/ui/components/ServerLaunchSection.tsx b/src/ui/components/ServerLaunchSection.tsx index 067ad02..313eebe 100644 --- a/src/ui/components/ServerLaunchSection.tsx +++ b/src/ui/components/ServerLaunchSection.tsx @@ -11,26 +11,26 @@ import Server from '../../resources/icons/server.svg' import Akebi from '../../resources/icons/akebi.svg' import './ServerLaunchSection.css' -import {dataDir} from '@tauri-apps/api/path' +import { dataDir } from '@tauri-apps/api/path' import { getGameExecutable } from '../../utils/game' import { patchGame, unpatchGame } from '../../utils/metadata' interface IState { - grasscutterEnabled: boolean; - buttonLabel: string; - checkboxLabel: string; - ip: string; - port: string; + grasscutterEnabled: boolean + buttonLabel: string + checkboxLabel: string + ip: string + port: string - ipPlaceholder: string; - portPlaceholder: string; + ipPlaceholder: string + portPlaceholder: string - portHelpText: string; + portHelpText: string - httpsLabel: string; - httpsEnabled: boolean; + httpsLabel: string + httpsEnabled: boolean - swag: boolean; + swag: boolean } export default class ServerLaunchSection extends React.Component<{}, IState> { @@ -48,7 +48,7 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { portHelpText: '', httpsLabel: '', httpsEnabled: false, - swag: false + swag: false, } this.toggleGrasscutter = this.toggleGrasscutter.bind(this) @@ -74,7 +74,7 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { portHelpText: await translate('help.port_help_text'), httpsLabel: await translate('main.https_enable'), httpsEnabled: config.https_enabled || false, - swag: config.swag_mode || false + swag: config.swag_mode || false, }) } @@ -85,7 +85,7 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { // Set state as well this.setState({ - grasscutterEnabled: config.toggle_grasscutter + grasscutterEnabled: config.toggle_grasscutter, }) await saveConfig(config) @@ -94,11 +94,11 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { async playGame(exe?: string, proc_name?: string) { const config = await getConfig() - if(!await getGameExecutable()) { + if (!(await getGameExecutable())) { alert('Game executable not set!') - return + return } - + // Connect to proxy if (config.toggle_grasscutter) { if (config.patch_metadata) { @@ -117,14 +117,16 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { await setConfigOption('last_port', this.state.port) await invoke('enable_process_watcher', { - process: proc_name || game_exe + process: proc_name || game_exe, }) if (config.use_internal_proxy) { // Set IP - await invoke('set_proxy_addr', { addr: (this.state.httpsEnabled ? 'https':'http') + '://' + this.state.ip + ':' + this.state.port }) + await invoke('set_proxy_addr', { + addr: (this.state.httpsEnabled ? 'https' : 'http') + '://' + this.state.ip + ':' + this.state.port, + }) // Connect to proxy - await invoke('connect', { port: 8365, certificatePath: await dataDir() + '\\cultivation\\ca' }) + await invoke('connect', { port: 8365, certificatePath: (await dataDir()) + '\\cultivation\\ca' }) } // Open server as well if the options are set @@ -137,21 +139,23 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { await invoke('run_jar', { path: config.grasscutter_path, executeIn: jarFolder, - javaPath: config.java_path || '' + javaPath: config.java_path || '', }) } } else { const unpatched = await unpatchGame() if (!unpatched) { - alert(`Could not unpatch game, aborting launch! (You can find your metadata backup in ${await dataDir()}\\cultivation\\)`) + alert( + `Could not unpatch game, aborting launch! (You can find your metadata backup in ${await dataDir()}\\cultivation\\)` + ) return } } - + // Launch the program const gameExists = await invoke('dir_exists', { - path: exe || config.game_install_path + path: exe || config.game_install_path, }) if (gameExists) await invoke('run_program', { path: exe || config.game_install_path }) @@ -175,7 +179,7 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { await invoke('run_jar', { path: config.grasscutter_path, executeIn: jarFolder, - javaPath: config.java_path || '' + javaPath: config.java_path || '', }) } @@ -194,7 +198,7 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { // First launch 3dm invoke('run_program', { - path: config.migoto_path + path: config.migoto_path, }) // Then play the game as normal @@ -203,13 +207,13 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { setIp(text: string) { this.setState({ - ip: text + ip: text, }) } setPort(text: string) { this.setState({ - port: text + port: text, }) } @@ -220,7 +224,7 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { // Set state as well this.setState({ - httpsEnabled: config.https_enabled + httpsEnabled: config.https_enabled, }) await saveConfig(config) @@ -230,40 +234,59 @@ export default class ServerLaunchSection extends React.Component<{}, IState> { return (
- +
- { - this.state.grasscutterEnabled && ( -
-
- - +
+ + - - -
+ }} + id="port" + key="port" + placeholder={this.state.portPlaceholder} + onChange={this.setPort} + initalValue={this.state.port} + /> + +
- ) - } - +
+ )}
- {this.state.buttonLabel} - { - this.state.swag && ( - <> - - - - - 3DM - - - - ) - } + + {this.state.buttonLabel} + + {this.state.swag && ( + <> + + + + + 3DM + + + )} @@ -271,4 +294,4 @@ export default class ServerLaunchSection extends React.Component<{}, IState> {
) } -} \ No newline at end of file +} diff --git a/src/ui/components/TopBar.css b/src/ui/components/TopBar.css index 30b3239..a13fd36 100644 --- a/src/ui/components/TopBar.css +++ b/src/ui/components/TopBar.css @@ -51,4 +51,4 @@ to { transform: rotate(360deg); } -} \ No newline at end of file +} diff --git a/src/ui/components/TopBar.tsx b/src/ui/components/TopBar.tsx index 26a5123..f1db052 100644 --- a/src/ui/components/TopBar.tsx +++ b/src/ui/components/TopBar.tsx @@ -12,15 +12,15 @@ import './TopBar.css' import { getConfig, setConfigOption } from '../../utils/configuration' interface IProps { - optFunc: () => void; - downFunc: () => void; - gameFunc: () => void; + optFunc: () => void + downFunc: () => void + gameFunc: () => void } interface IState { - version: string; - clicks: number; - intv: NodeJS.Timeout | null; + version: string + clicks: number + intv: NodeJS.Timeout | null } export default class TopBar extends React.Component { @@ -30,7 +30,7 @@ export default class TopBar extends React.Component { this.state = { version: '0.0.0', clicks: 0, - intv: null + intv: null, } this.activateClick = this.activateClick.bind(this) @@ -59,10 +59,10 @@ export default class TopBar extends React.Component { setTimeout(() => { // Gotta clear it so it goes back to regular colors this.setState({ - clicks: 0 + clicks: 0, }) }, 600) - + // Activate... SWAG MODE await setConfigOption('swag_mode', true) @@ -75,7 +75,7 @@ export default class TopBar extends React.Component { if (this.state.clicks < 3) { this.setState({ clicks: this.state.clicks + 1, - intv: setTimeout(() => this.setState({ clicks: 0 }), 1500) + intv: setTimeout(() => this.setState({ clicks: 0 }), 1500), }) return @@ -89,29 +89,31 @@ export default class TopBar extends React.Component { - {this.state?.version} + + {this.state?.version} + +
+ {/** + * HEY YOU + * + * If you're looking at the source code to find the swag mode thing, that's okay! If you're not, move along... + * Just do me a favor and don't go telling everyone about how you found it. If you are just helping someone who + * for some reason needs it, that's fine, but not EVERYONE needs it, which is why it exists in the first place. + */} +
+ ?
- { - /** - * HEY YOU - * - * If you're looking at the source code to find the swag mode thing, that's okay! If you're not, move along... - * Just do me a favor and don't go telling everyone about how you found it. If you are just helping someone who - * for some reason needs it, that's fine, but not EVERYONE needs it, which is why it exists in the first place. - */ - } -
?
-
+
close
-
+
minimize
-
+
settings
-
+
downloads
{/*
@@ -121,4 +123,4 @@ export default class TopBar extends React.Component {
) } -} \ No newline at end of file +} diff --git a/src/ui/components/common/BigButton.css b/src/ui/components/common/BigButton.css index ae4303d..045008d 100644 --- a/src/ui/components/common/BigButton.css +++ b/src/ui/components/common/BigButton.css @@ -27,4 +27,4 @@ .BigButton.disabled:hover { background: linear-gradient(#949494, #9c9c9c); -} \ No newline at end of file +} diff --git a/src/ui/components/common/BigButton.tsx b/src/ui/components/common/BigButton.tsx index 5b6cbe7..6fa10bd 100644 --- a/src/ui/components/common/BigButton.tsx +++ b/src/ui/components/common/BigButton.tsx @@ -2,14 +2,14 @@ import React from 'react' import './BigButton.css' interface IProps { - children: React.ReactNode; - onClick: () => unknown; - id: string; - disabled?: boolean; + children: React.ReactNode + onClick: () => unknown + id: string + disabled?: boolean } interface IState { - disabled?: boolean; + disabled?: boolean } export default class BigButton extends React.Component { @@ -17,7 +17,7 @@ export default class BigButton extends React.Component { super(props) this.state = { - disabled: this.props.disabled + disabled: this.props.disabled, } this.handleClick = this.handleClick.bind(this) @@ -25,7 +25,7 @@ export default class BigButton extends React.Component { static getDerivedStateFromProps(props: IProps, _state: IState) { return { - disabled: props.disabled + disabled: props.disabled, } } @@ -37,9 +37,13 @@ export default class BigButton extends React.Component { render() { return ( -
+
{this.props.children}
) } -} \ No newline at end of file +} diff --git a/src/ui/components/common/Checkbox.css b/src/ui/components/common/Checkbox.css index b42c027..c485e36 100644 --- a/src/ui/components/common/Checkbox.css +++ b/src/ui/components/common/Checkbox.css @@ -1,4 +1,4 @@ -.Checkbox input[type="checkbox"] { +.Checkbox input[type='checkbox'] { display: none; } @@ -17,10 +17,10 @@ .CheckboxDisplay img { height: 100%; - filter: invert(99%) sepia(0%) saturate(1188%) hue-rotate(186deg) brightness(97%) contrast(67%) + filter: invert(99%) sepia(0%) saturate(1188%) hue-rotate(186deg) brightness(97%) contrast(67%); } .Checkbox label { display: flex; flex-direction: row; -} \ No newline at end of file +} diff --git a/src/ui/components/common/Checkbox.tsx b/src/ui/components/common/Checkbox.tsx index 3eefc2c..581392f 100644 --- a/src/ui/components/common/Checkbox.tsx +++ b/src/ui/components/common/Checkbox.tsx @@ -4,9 +4,9 @@ import checkmark from '../../../resources/icons/check.svg' import './Checkbox.css' interface IProps { - label?: string, - checked: boolean, - onChange: () => void, + label?: string + checked: boolean + onChange: () => void id: string } @@ -19,14 +19,14 @@ export default class Checkbox extends React.Component { super(props) this.state = { - checked: props.checked + checked: props.checked, } } static getDerivedStateFromProps(props: IProps, state: IState) { if (props.checked !== state.checked) { return { - checked: props.checked + checked: props.checked, } } @@ -41,14 +41,12 @@ export default class Checkbox extends React.Component { render() { return (
- +
) } -} \ No newline at end of file +} diff --git a/src/ui/components/common/DirInput.css b/src/ui/components/common/DirInput.css index 6dff2f2..5d88404 100644 --- a/src/ui/components/common/DirInput.css +++ b/src/ui/components/common/DirInput.css @@ -24,4 +24,4 @@ .FileSelectIcon img { height: 100%; -} \ No newline at end of file +} diff --git a/src/ui/components/common/DirInput.tsx b/src/ui/components/common/DirInput.tsx index 510969b..16de06b 100644 --- a/src/ui/components/common/DirInput.tsx +++ b/src/ui/components/common/DirInput.tsx @@ -14,7 +14,7 @@ interface IProps { readonly?: boolean placeholder?: string folder?: boolean - customClearBehaviour?: () => void, + customClearBehaviour?: () => void openFolder?: string } @@ -31,7 +31,7 @@ export default class DirInput extends React.Component { this.state = { value: props.value || '', placeholder: this.props.placeholder || 'Select file or folder...', - folder: this.props.folder || false + folder: this.props.folder || false, } this.handleIconClick = this.handleIconClick.bind(this) @@ -54,8 +54,8 @@ export default class DirInput extends React.Component { async componentDidMount() { if (!this.props.placeholder) { const translation = await translate('components.select_file') - this.setState( { - placeholder: translation + this.setState({ + placeholder: translation, }) } } @@ -65,15 +65,13 @@ export default class DirInput extends React.Component { if (this.state.folder) { path = await open({ - directory: true + directory: true, }) } else { console.log(this.props.openFolder) path = await open({ - filters: [ - { name: 'Files', extensions: this.props.extensions || ['*'] } - ], - defaultPath: this.props.openFolder + filters: [{ name: 'Files', extensions: this.props.extensions || ['*'] }], + defaultPath: this.props.openFolder, }) } @@ -81,7 +79,7 @@ export default class DirInput extends React.Component { if (!path) return this.setState({ - value: path + value: path, }) if (this.props.onChange) this.props.onChange(path) @@ -89,12 +87,13 @@ export default class DirInput extends React.Component { render() { return ( -
+
{ + readOnly={this.props.readonly !== undefined ? this.props.readonly : true} + onChange={(text: string) => { this.setState({ value: text }) if (this.props.onChange) this.props.onChange(text) @@ -108,4 +107,4 @@ export default class DirInput extends React.Component {
) } -} \ No newline at end of file +} diff --git a/src/ui/components/common/DownloadList.css b/src/ui/components/common/DownloadList.css index 5be9bca..7a63fbc 100644 --- a/src/ui/components/common/DownloadList.css +++ b/src/ui/components/common/DownloadList.css @@ -4,4 +4,4 @@ flex: 1; overflow-y: auto; padding: 10px; -} \ No newline at end of file +} diff --git a/src/ui/components/common/DownloadList.tsx b/src/ui/components/common/DownloadList.tsx index 8d8fe66..6bbd906 100644 --- a/src/ui/components/common/DownloadList.tsx +++ b/src/ui/components/common/DownloadList.tsx @@ -5,7 +5,7 @@ import DownloadSection from './DownloadSection' import './DownloadList.css' interface IProps { - downloadManager: DownloadHandler; + downloadManager: DownloadHandler } export default class DownloadList extends React.Component { @@ -16,17 +16,14 @@ export default class DownloadList extends React.Component { render() { const list = this.props.downloadManager.getDownloads().map((download) => { return ( - + ) }) - - return ( -
- { - list.length > 0 ? list : 'No downloads present' - } -
- ) + return
{list.length > 0 ? list : 'No downloads present'}
} -} \ No newline at end of file +} diff --git a/src/ui/components/common/DownloadSection.css b/src/ui/components/common/DownloadSection.css index 0c47ded..f254415 100644 --- a/src/ui/components/common/DownloadSection.css +++ b/src/ui/components/common/DownloadSection.css @@ -26,4 +26,4 @@ .DownloadStatus { text-align: right; -} \ No newline at end of file +} diff --git a/src/ui/components/common/DownloadSection.tsx b/src/ui/components/common/DownloadSection.tsx index 373b238..0b9b4ac 100644 --- a/src/ui/components/common/DownloadSection.tsx +++ b/src/ui/components/common/DownloadSection.tsx @@ -5,8 +5,8 @@ import ProgressBar from './ProgressBar' import './DownloadSection.css' interface IProps { - downloadManager: DownloadHandler; - downloadName: string; + downloadManager: DownloadHandler + downloadName: string } export default class DownloadSection extends React.Component { @@ -32,4 +32,4 @@ export default class DownloadSection extends React.Component {
) } -} \ No newline at end of file +} diff --git a/src/ui/components/common/HelpButton.css b/src/ui/components/common/HelpButton.css index 6b40109..efade89 100644 --- a/src/ui/components/common/HelpButton.css +++ b/src/ui/components/common/HelpButton.css @@ -30,4 +30,4 @@ right: -450%; width: 200px; height: 120px; -} \ No newline at end of file +} diff --git a/src/ui/components/common/HelpButton.tsx b/src/ui/components/common/HelpButton.tsx index 3baf1bb..de78c8c 100644 --- a/src/ui/components/common/HelpButton.tsx +++ b/src/ui/components/common/HelpButton.tsx @@ -5,7 +5,7 @@ import Help from '../../../resources/icons/help.svg' import MiniDialog from '../MiniDialog' interface IProps { - children?: React.ReactNode[] | React.ReactNode; + children?: React.ReactNode[] | React.ReactNode contents?: string id?: string } @@ -19,7 +19,7 @@ export default class HelpButton extends React.Component { super(props) this.state = { - opened: false + opened: false, } this.setOpen = this.setOpen.bind(this) @@ -41,14 +41,15 @@ export default class HelpButton extends React.Component {
-
- - {this.props.contents || this.props.children} - +
+ {this.props.contents || this.props.children}
) } -} \ No newline at end of file +} diff --git a/src/ui/components/common/MainProgressBar.tsx b/src/ui/components/common/MainProgressBar.tsx index f43fc52..ff6d023 100644 --- a/src/ui/components/common/MainProgressBar.tsx +++ b/src/ui/components/common/MainProgressBar.tsx @@ -4,15 +4,15 @@ import Tr from '../../../utils/language' import './ProgressBar.css' interface IProps { - downloadManager: DownloadHandler, + downloadManager: DownloadHandler } interface IState { - average: number, - files: number, - extracting: number, - total: number, - speed: string, + average: number + files: number + extracting: number + total: number + speed: string } /** @@ -29,7 +29,7 @@ export default class ProgressBar extends React.Component { files, extracting, total: totalSize, - speed: '0 B/s' + speed: '0 B/s', } } @@ -51,20 +51,23 @@ export default class ProgressBar extends React.Component { return (
-
{ - // Handles no files downloading - if (this.state.files === 0) { - return '100' - } +
{ + // Handles no files downloading + if (this.state.files === 0) { + return '100' + } - if (this.state.total <= 0) { - return '0' - } + if (this.state.total <= 0) { + return '0' + } - return this.state.average - })()}%`, - }}>
+ return this.state.average + })()}%`, + }} + >
@@ -75,4 +78,4 @@ export default class ProgressBar extends React.Component {
) } -} \ No newline at end of file +} diff --git a/src/ui/components/common/ProgressBar.css b/src/ui/components/common/ProgressBar.css index 7e57421..eaed6f1 100644 --- a/src/ui/components/common/ProgressBar.css +++ b/src/ui/components/common/ProgressBar.css @@ -1,4 +1,5 @@ -.ProgressBar, .InnerProgress { +.ProgressBar, +.InnerProgress { border-radius: 4px; } @@ -91,4 +92,4 @@ .downloadStop:hover { cursor: pointer; -} \ No newline at end of file +} diff --git a/src/ui/components/common/ProgressBar.tsx b/src/ui/components/common/ProgressBar.tsx index 6194f04..650dd22 100644 --- a/src/ui/components/common/ProgressBar.tsx +++ b/src/ui/components/common/ProgressBar.tsx @@ -1,20 +1,20 @@ import React from 'react' import { capitalize } from '../../../utils/string' -import Stop from '../../../resources/icons/close.svg' +import Stop from '../../../resources/icons/close.svg' import './ProgressBar.css' import DownloadHandler from '../../../utils/download' import { translate } from '../../../utils/language' interface IProps { - path: string, - downloadManager: DownloadHandler, + path: string + downloadManager: DownloadHandler } interface IState { - progress: number, - status: string, - total: number, + progress: number + status: string + total: number } export default class ProgressBar extends React.Component { @@ -36,7 +36,7 @@ export default class ProgressBar extends React.Component { const prog = this.props.downloadManager.getDownloadProgress(this.props.path) this.setState({ progress: prog?.progress || 0, - status: await translate(`download_status.${prog?.status || 'stopped'}`) || 'stopped', + status: (await translate(`download_status.${prog?.status || 'stopped'}`)) || 'stopped', total: prog?.total || 0, }) @@ -54,24 +54,29 @@ export default class ProgressBar extends React.Component { render() { return (
-
+
-
{ - // Handles files with content-lengths of 0 - if (this.state.status === 'finished') { - return '100' - } +
{ + // Handles files with content-lengths of 0 + if (this.state.status === 'finished') { + return '100' + } - if (this.state.total <= 0) { - return '0' - } + if (this.state.total <= 0) { + return '0' + } - return this.state.progress / this.state.total * 100 - })()}%`, - }}>
+ return (this.state.progress / this.state.total) * 100 + })()}%`, + }} + >
@@ -80,10 +85,8 @@ export default class ProgressBar extends React.Component {
-
- {capitalize(this.state.status) || 'Waiting'} -
+
{capitalize(this.state.status) || 'Waiting'}
) } -} \ No newline at end of file +} diff --git a/src/ui/components/common/TextInput.css b/src/ui/components/common/TextInput.css index a952cf0..69e8793 100644 --- a/src/ui/components/common/TextInput.css +++ b/src/ui/components/common/TextInput.css @@ -17,7 +17,7 @@ display: inline-block; position: absolute; right: 16%; - + filter: invert(99%) sepia(0%) saturate(1188%) hue-rotate(186deg) brightness(97%) contrast(67%); } @@ -28,4 +28,4 @@ .TextInputClear { height: 100%; -} \ No newline at end of file +} diff --git a/src/ui/components/common/TextInput.tsx b/src/ui/components/common/TextInput.tsx index 1efac23..22996f9 100644 --- a/src/ui/components/common/TextInput.tsx +++ b/src/ui/components/common/TextInput.tsx @@ -4,15 +4,15 @@ import './TextInput.css' import Close from '../../../resources/icons/close.svg' interface IProps { - value?: string; - initalValue?: string; - placeholder?: string; - onChange?: (value: string) => void; - readOnly?: boolean; - id?: string; - clearable?: boolean; - customClearBehaviour?: () => void; - style?: React.CSSProperties; + value?: string + initalValue?: string + placeholder?: string + onChange?: (value: string) => void + readOnly?: boolean + id?: string + clearable?: boolean + customClearBehaviour?: () => void + style?: React.CSSProperties } interface IState { @@ -24,14 +24,14 @@ export default class TextInput extends React.Component { super(props) this.state = { - value: props.value || '' + value: props.value || '', } } async componentDidMount() { if (this.props.initalValue) { this.setState({ - value: this.props.initalValue + value: this.props.initalValue, }) } } @@ -43,26 +43,35 @@ export default class TextInput extends React.Component { render() { return (
- { - this.setState({ value: e.target.value }) - if (this.props.onChange) this.props.onChange(e.target.value) - }} /> - { - this.props.clearable ? -
{ + { + this.setState({ value: e.target.value }) + if (this.props.onChange) this.props.onChange(e.target.value) + }} + /> + {this.props.clearable ? ( +
{ // Run custom behaviour first if (this.props.customClearBehaviour) return this.props.customClearBehaviour() this.setState({ value: '' }) - + if (this.props.onChange) this.props.onChange('') this.forceUpdate() - }}> - -
: null - } + }} + > + +
+ ) : null}
) } -} \ No newline at end of file +} diff --git a/src/ui/components/menu/Divider.css b/src/ui/components/menu/Divider.css index a0901ea..03de97f 100644 --- a/src/ui/components/menu/Divider.css +++ b/src/ui/components/menu/Divider.css @@ -1,4 +1,3 @@ - .Divider { display: flex; flex-direction: row; @@ -13,4 +12,4 @@ .DividerLine { width: 60%; border-top: 1px solid #ccc; -} \ No newline at end of file +} diff --git a/src/ui/components/menu/Divider.tsx b/src/ui/components/menu/Divider.tsx index 6a091cd..c516e6f 100644 --- a/src/ui/components/menu/Divider.tsx +++ b/src/ui/components/menu/Divider.tsx @@ -10,4 +10,4 @@ export default class Divider extends React.Component {
) } -} \ No newline at end of file +} diff --git a/src/ui/components/menu/Downloads.css b/src/ui/components/menu/Downloads.css index 60f7c6e..24a954a 100644 --- a/src/ui/components/menu/Downloads.css +++ b/src/ui/components/menu/Downloads.css @@ -28,4 +28,4 @@ .DownloadMenuSection .HelpButton img { filter: none; -} \ No newline at end of file +} diff --git a/src/ui/components/menu/Downloads.tsx b/src/ui/components/menu/Downloads.tsx index f4c8f8a..a97b769 100644 --- a/src/ui/components/menu/Downloads.tsx +++ b/src/ui/components/menu/Downloads.tsx @@ -20,8 +20,8 @@ const DEV_DOWNLOAD = 'https://nightly.link/Grasscutters/Grasscutter/workflows/bu const RESOURCES_DOWNLOAD = 'https://gitlab.com/yukiz/GrasscutterResources/-/archive/2.8/GrasscutterResources-2.8.zip' interface IProps { - closeFn: () => void; - downloadManager: DownloadHandler; + closeFn: () => void + downloadManager: DownloadHandler } interface IState { @@ -41,7 +41,7 @@ export default class Downloads extends React.Component { resources_downloading: this.props.downloadManager.downloadingResources(), repo_downloading: this.props.downloadManager.downloadingRepo(), grasscutter_set: false, - resources_exist: false + resources_exist: false, } this.getGrasscutterFolder = this.getGrasscutterFolder.bind(this) @@ -63,7 +63,7 @@ export default class Downloads extends React.Component { if (!gc_path || gc_path === '') { this.setState({ grasscutter_set: false, - resources_exist: false + resources_exist: false, }) return @@ -72,15 +72,17 @@ export default class Downloads extends React.Component { const path = gc_path.substring(0, gc_path.lastIndexOf('\\')) if (gc_path) { - const resources_exist: boolean = await invoke('dir_exists', { - path: path + '\\resources' - }) as boolean && !(await invoke('dir_is_empty', { - path: path + '\\resources' - })) as boolean + const resources_exist: boolean = + ((await invoke('dir_exists', { + path: path + '\\resources', + })) as boolean) && + (!(await invoke('dir_is_empty', { + path: path + '\\resources', + })) as boolean) this.setState({ grasscutter_set: gc_path !== '', - resources_exist + resources_exist, }) } } @@ -109,7 +111,7 @@ export default class Downloads extends React.Component { async downloadGrasscutterStableRepo() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(STABLE_REPO_DOWNLOAD, folder + '\\grasscutter_repo.zip', () =>{ + this.props.downloadManager.addDownload(STABLE_REPO_DOWNLOAD, folder + '\\grasscutter_repo.zip', () => { unzip(folder + '\\grasscutter_repo.zip', folder + '\\', this.toggleButtons) }) @@ -118,7 +120,7 @@ export default class Downloads extends React.Component { async downloadGrasscutterDevRepo() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(DEV_REPO_DOWNLOAD, folder + '\\grasscutter_repo.zip', () =>{ + this.props.downloadManager.addDownload(DEV_REPO_DOWNLOAD, folder + '\\grasscutter_repo.zip', () => { unzip(folder + '\\grasscutter_repo.zip', folder + '\\', this.toggleButtons) }) @@ -127,7 +129,7 @@ export default class Downloads extends React.Component { async downloadGrasscutterStable() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(STABLE_DOWNLOAD, folder + '\\grasscutter.zip', () =>{ + this.props.downloadManager.addDownload(STABLE_DOWNLOAD, folder + '\\grasscutter.zip', () => { unzip(folder + '\\grasscutter.zip', folder + '\\', this.toggleButtons) }) @@ -135,11 +137,11 @@ export default class Downloads extends React.Component { this.downloadGrasscutterStableRepo() this.toggleButtons() - } + } async downloadGrasscutterLatest() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(DEV_DOWNLOAD, folder + '\\grasscutter.zip', () =>{ + this.props.downloadManager.addDownload(DEV_DOWNLOAD, folder + '\\grasscutter.zip', () => { unzip(folder + '\\grasscutter.zip', folder + '\\', this.toggleButtons) }) @@ -152,12 +154,14 @@ export default class Downloads extends React.Component { async downloadResources() { const folder = await this.getGrasscutterFolder() this.props.downloadManager.addDownload(RESOURCES_DOWNLOAD, folder + '\\resources.zip', async () => { - // Delete the existing folder if it exists - if (await invoke('dir_exists', { - path: folder + '\\resources' - })) { + // Delete the existing folder if it exists + if ( + await invoke('dir_exists', { + path: folder + '\\resources', + }) + ) { await invoke('dir_delete', { - path: folder + '\\resources' + path: folder + '\\resources', }) } @@ -165,7 +169,7 @@ export default class Downloads extends React.Component { // Rename folder to resources invoke('rename', { path: folder + '\\Resources', - newName: 'resources' + newName: 'resources', }) this.toggleButtons() @@ -190,32 +194,40 @@ export default class Downloads extends React.Component { render() { return ( -
-
- +
+
+
-
- +
+
-
-
- +
+
+
-
- +
+
@@ -223,32 +235,48 @@ export default class Downloads extends React.Component { -
-
- +
+
+
-
- +
+
-
-
- +
+
+
-
- +
+
@@ -256,15 +284,19 @@ export default class Downloads extends React.Component { -
-
+
+
-
- +
+
@@ -272,4 +304,4 @@ export default class Downloads extends React.Component {
) } -} \ No newline at end of file +} diff --git a/src/ui/components/menu/Game.css b/src/ui/components/menu/Game.css index 6308735..505005b 100644 --- a/src/ui/components/menu/Game.css +++ b/src/ui/components/menu/Game.css @@ -34,4 +34,4 @@ .GameDownloadDir .DirInput .TextInputWrapper input { width: 80%; -} \ No newline at end of file +} diff --git a/src/ui/components/menu/Game.tsx b/src/ui/components/menu/Game.tsx index 68cd73c..4a6e77f 100644 --- a/src/ui/components/menu/Game.tsx +++ b/src/ui/components/menu/Game.tsx @@ -12,14 +12,14 @@ import { unzip } from '../../../utils/zipUtils' const GAME_DOWNLOAD = '' interface IProps { - closeFn: () => void; - downloadManager: DownloadHandler; + closeFn: () => void + downloadManager: DownloadHandler } interface IState { - gameDownloading: boolean; - gameDownloadFolder: string; - dirPlaceholder: string; + gameDownloading: boolean + gameDownloadFolder: string + dirPlaceholder: string } export default class Downloads extends React.Component { @@ -29,7 +29,7 @@ export default class Downloads extends React.Component { this.state = { gameDownloading: false, gameDownloadFolder: '', - dirPlaceholder: '' + dirPlaceholder: '', } this.downloadGame = this.downloadGame.bind(this) @@ -37,7 +37,7 @@ export default class Downloads extends React.Component { async componentDidMount() { this.setState({ - dirPlaceholder: await translate('components.select_folder') + dirPlaceholder: await translate('components.select_folder'), }) console.log(this.state) @@ -45,39 +45,51 @@ export default class Downloads extends React.Component { async downloadGame() { const folder = this.state.gameDownloadFolder - this.props.downloadManager.addDownload(GAME_DOWNLOAD, folder + '\\game.zip', () =>{ + this.props.downloadManager.addDownload(GAME_DOWNLOAD, folder + '\\game.zip', () => { unzip(folder + '\\game.zip', folder + '\\', () => { this.setState({ - gameDownloading: false + gameDownloading: false, }) }) }) this.setState({ - gameDownloading: true + gameDownloading: true, }) } render() { return ( - +
- { - this.state.gameDownloadFolder !== '' && !this.state.gameDownloading ? - Download Game - : null} disabled>Download Game - } + {this.state.gameDownloadFolder !== '' && !this.state.gameDownloading ? ( + + Download Game + + ) : ( + null} disabled> + Download Game + + )}
- +
- this.setState({ - gameDownloadFolder: value - })}/> + + this.setState({ + gameDownloadFolder: value, + }) + } + />
) } -} \ No newline at end of file +} diff --git a/src/ui/components/menu/Menu.css b/src/ui/components/menu/Menu.css index d8e64a1..ea6e133 100644 --- a/src/ui/components/menu/Menu.css +++ b/src/ui/components/menu/Menu.css @@ -12,7 +12,7 @@ background: #fff; padding: 20px; border-radius: 10px; - + box-shadow: 0px 0px 5px 3px rgba(0, 0, 0, 0.2); overflow-y: auto; @@ -52,4 +52,4 @@ .MenuExit img { height: 100%; -} \ No newline at end of file +} diff --git a/src/ui/components/menu/Menu.tsx b/src/ui/components/menu/Menu.tsx index eb723ab..f57f3e7 100644 --- a/src/ui/components/menu/Menu.tsx +++ b/src/ui/components/menu/Menu.tsx @@ -4,10 +4,10 @@ import './Menu.css' import Close from '../../../resources/icons/close.svg' interface IProps { - children: React.ReactNode[] | React.ReactNode; - className?: string; - heading: string; - closeFn: () => void; + children: React.ReactNode[] | React.ReactNode + className?: string + heading: string + closeFn: () => void } export default class Menu extends React.Component { @@ -18,16 +18,18 @@ export default class Menu extends React.Component { render() { return ( @@ -270,11 +270,7 @@ export default class Options extends React.Component {
-