You've already forked AstralRinth
forked from didirus/AstralRinth
Fix auto updater, add failure message, fix modals (#2335)
* Fix auto updater, add failure message, fix modals * Fix ads hiding, updater UI * dummy version, fix gh actions cache * fix release conf * actual version bump * Fix ads hiding sometimes * Fix event state init * fix remaining bugs * Fix lint on linux * Fix deep linking on Windows * Fix ad links opening multiple times
This commit is contained in:
21
.github/workflows/app-release.yml
vendored
21
.github/workflows/app-release.yml
vendored
@@ -44,7 +44,24 @@ jobs:
|
|||||||
- name: Setup rust cache
|
- name: Setup rust cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: target/**
|
path: |
|
||||||
|
target/**
|
||||||
|
!target/*/release/bundle/*/*.dmg
|
||||||
|
!target/*/release/bundle/*/*.app.tar.gz
|
||||||
|
!target/*/release/bundle/*/*.app.tar.gz.sig
|
||||||
|
!target/release/bundle/*/*.dmg
|
||||||
|
!target/release/bundle/*/*.app.tar.gz
|
||||||
|
!target/release/bundle/*/*.app.tar.gz.sig
|
||||||
|
|
||||||
|
!target/release/bundle/*/*.AppImage
|
||||||
|
!target/release/bundle/*/*.AppImage.tar.gz
|
||||||
|
!target/release/bundle/*/*.AppImage.tar.gz.sig
|
||||||
|
!target/release/bundle/*/*.deb
|
||||||
|
!target/release/bundle/*/*.rpm
|
||||||
|
|
||||||
|
!target/release/bundle/*/*.msi
|
||||||
|
!target/release/bundle/*/*.msi.zip
|
||||||
|
!target/release/bundle/*/*.msi.zip.sig
|
||||||
key: ${{ runner.os }}-rust-target-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-rust-target-${{ hashFiles('**/Cargo.lock') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-rust-target-
|
${{ runner.os }}-rust-target-
|
||||||
@@ -124,7 +141,7 @@ jobs:
|
|||||||
target/release/bundle/*/*.AppImage.tar.gz.sig
|
target/release/bundle/*/*.AppImage.tar.gz.sig
|
||||||
target/release/bundle/*/*.deb
|
target/release/bundle/*/*.deb
|
||||||
target/release/bundle/*/*.rpm
|
target/release/bundle/*/*.rpm
|
||||||
|
|
||||||
target/release/bundle/*/*.msi
|
target/release/bundle/*/*.msi
|
||||||
target/release/bundle/*/*.msi.zip
|
target/release/bundle/*/*.msi.zip
|
||||||
target/release/bundle/*/*.msi.zip.sig
|
target/release/bundle/*/*.msi.zip.sig
|
||||||
|
|||||||
90
Cargo.lock
generated
90
Cargo.lock
generated
@@ -166,6 +166,30 @@ dependencies = [
|
|||||||
"zstd-safe 7.2.1",
|
"zstd-safe 7.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-executor"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7"
|
||||||
|
dependencies = [
|
||||||
|
"async-task",
|
||||||
|
"concurrent-queue",
|
||||||
|
"fastrand",
|
||||||
|
"futures-lite",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-fs"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
|
||||||
|
dependencies = [
|
||||||
|
"async-lock",
|
||||||
|
"blocking",
|
||||||
|
"futures-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-io"
|
name = "async-io"
|
||||||
version = "2.3.4"
|
version = "2.3.4"
|
||||||
@@ -5053,9 +5077,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swift-rs"
|
name = "swift-rs"
|
||||||
version = "1.0.6"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1bbdb58577b6301f8d17ae2561f32002a5bae056d444e0f69e611e504a276204"
|
checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -5227,9 +5251,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri"
|
name = "tauri"
|
||||||
version = "2.0.0-rc.6"
|
version = "2.0.0-rc.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "997e79de4c7a13b494a02c8104aa146a5d871ce83e5943e522bc5f8f35c8dab8"
|
checksum = "e8345ccc676ef16e26b61fc0f5340b4e770678b1e1f53f08c69ebdac5e56b422"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -5277,9 +5301,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-build"
|
name = "tauri-build"
|
||||||
version = "2.0.0-rc.6"
|
version = "2.0.0-rc.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "032b966611a9324c2185fb9039ccfb938dbe00ec96fa1fe1596c9a1a98a6c87b"
|
checksum = "7d5ad5fcfaf02cf79aa6727f6c5df38567d8dce172b00b62690c6bc46c08b7ce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cargo_toml",
|
"cargo_toml",
|
||||||
@@ -5301,9 +5325,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-codegen"
|
name = "tauri-codegen"
|
||||||
version = "2.0.0-rc.6"
|
version = "2.0.0-rc.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f4138f3ee5fafa703c4504da58b6b94693655d0ddff8daf1e831b6dc04f4125"
|
checksum = "809ef6316726fc72593d296cf6f4e7461326e310c313d6a6c42b6e7f1e2671cf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"brotli",
|
"brotli",
|
||||||
@@ -5328,9 +5352,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-macros"
|
name = "tauri-macros"
|
||||||
version = "2.0.0-rc.5"
|
version = "2.0.0-rc.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a5995206394cd30411fc5c8ae195e498357f63e11ed960ea32b53512dcb2a5a5"
|
checksum = "1359e8861d210d25731f8b1bfbb4d111dd06406cf73c59659366ef450364d811"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -5342,9 +5366,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin"
|
name = "tauri-plugin"
|
||||||
version = "2.0.0-rc.6"
|
version = "2.0.0-rc.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4658d4bfb0e9c8abc8fa9d3e45b4e5fcbfe1be850316d96cefa6a1d4ffc215be"
|
checksum = "a7dded420c86183f592d0fe925ef9447f41e26fa79f0bdfef8d3f17bfbcdbfb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"glob",
|
"glob",
|
||||||
@@ -5453,6 +5477,21 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-single-instance"
|
||||||
|
version = "2.0.0-rc.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d73c92c98d44d4daba0118d905f45243dfcd6eaac82216c3382a02d17cb74cf2"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tauri",
|
||||||
|
"thiserror",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-updater"
|
name = "tauri-plugin-updater"
|
||||||
version = "2.0.0-rc.1"
|
version = "2.0.0-rc.1"
|
||||||
@@ -5499,9 +5538,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-runtime"
|
name = "tauri-runtime"
|
||||||
version = "2.0.0-rc.6"
|
version = "2.0.0-rc.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7c0830152f7e56a6c43080ced8f1c30a785a237ca3cfaa559ddf52d4be633275"
|
checksum = "75c72b844f387bfc3341c355f3e16b8cbf4161848fa4e348670effb222cd3ba5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dpi",
|
"dpi",
|
||||||
"gtk",
|
"gtk",
|
||||||
@@ -5518,9 +5557,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-runtime-wry"
|
name = "tauri-runtime-wry"
|
||||||
version = "2.0.0-rc.6"
|
version = "2.0.0-rc.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6f185bd051f52bece7ef2b197e1f285dab57e3891faa8eacc991459792b077c1"
|
checksum = "73accf936a7cd01d1382de7850726fdf6c1f6ab3b01ccb7a0950cb852e332596"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cocoa 0.26.0",
|
"cocoa 0.26.0",
|
||||||
"gtk",
|
"gtk",
|
||||||
@@ -5542,9 +5581,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-utils"
|
name = "tauri-utils"
|
||||||
version = "2.0.0-rc.6"
|
version = "2.0.0-rc.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f04e02a821a99d544d93b44870799aaf75c8c0dda1853baf064261da3070b892"
|
checksum = "d53d9fe87e985b273696ae22ce2b9f099a8f1b44bc8fb127467bda5fcb3e4371"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli",
|
"brotli",
|
||||||
"cargo_metadata",
|
"cargo_metadata",
|
||||||
@@ -5611,7 +5650,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "theseus"
|
name = "theseus"
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
"async-tungstenite",
|
"async-tungstenite",
|
||||||
@@ -5662,7 +5701,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "theseus_gui"
|
name = "theseus_gui"
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"cocoa 0.25.0",
|
"cocoa 0.25.0",
|
||||||
@@ -5686,6 +5725,7 @@ dependencies = [
|
|||||||
"tauri-plugin-dialog",
|
"tauri-plugin-dialog",
|
||||||
"tauri-plugin-os",
|
"tauri-plugin-os",
|
||||||
"tauri-plugin-shell",
|
"tauri-plugin-shell",
|
||||||
|
"tauri-plugin-single-instance",
|
||||||
"tauri-plugin-updater",
|
"tauri-plugin-updater",
|
||||||
"tauri-plugin-window-state",
|
"tauri-plugin-window-state",
|
||||||
"theseus",
|
"theseus",
|
||||||
@@ -6068,9 +6108,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tray-icon"
|
name = "tray-icon"
|
||||||
version = "0.15.1"
|
version = "0.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b92252d649d771105448969f2b2dda4342ba48b77731b60d37c93665e26615b"
|
checksum = "131a65b2cef2081bc14dbcd414c906edbfa3bb5323dd7e748cc298614681196b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core-graphics 0.24.0",
|
"core-graphics 0.24.0",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
@@ -7114,9 +7154,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
|
checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-broadcast",
|
"async-broadcast",
|
||||||
|
"async-executor",
|
||||||
|
"async-fs",
|
||||||
|
"async-io",
|
||||||
|
"async-lock",
|
||||||
"async-process",
|
"async-process",
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
|
"async-task",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"blocking",
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
"event-listener",
|
"event-listener",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>Modrinth App</title>
|
<title>Modrinth App</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="/src/assets/stylesheets/global.scss" />
|
<link rel="stylesheet" href="/src/assets/stylesheets/global.scss" />
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@modrinth/app-frontend",
|
"name": "@modrinth/app-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.8.4",
|
"version": "0.8.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
|
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
|
||||||
"@tauri-apps/plugin-window-state": "^2.0.0-rc.0",
|
"@tauri-apps/plugin-window-state": "^2.0.0-rc.0",
|
||||||
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
|
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
|
||||||
|
"@tauri-apps/plugin-updater": "^2.0.0-rc.0",
|
||||||
"@vintl/vintl": "^4.4.1",
|
"@vintl/vintl": "^4.4.1",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"floating-vue": "^5.2.2",
|
"floating-vue": "^5.2.2",
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref, onMounted } from 'vue'
|
import { computed, ref, onMounted } from 'vue'
|
||||||
import { RouterView, RouterLink, useRouter, useRoute } from 'vue-router'
|
import { RouterView, RouterLink, useRouter, useRoute } from 'vue-router'
|
||||||
import { HomeIcon, SearchIcon, LibraryIcon, PlusIcon, SettingsIcon, XIcon } from '@modrinth/assets'
|
import {
|
||||||
|
HomeIcon,
|
||||||
|
SearchIcon,
|
||||||
|
LibraryIcon,
|
||||||
|
PlusIcon,
|
||||||
|
SettingsIcon,
|
||||||
|
XIcon,
|
||||||
|
DownloadIcon,
|
||||||
|
} from '@modrinth/assets'
|
||||||
import { Button, Notifications } from '@modrinth/ui'
|
import { Button, Notifications } from '@modrinth/ui'
|
||||||
import { useLoading, useTheming } from '@/store/state'
|
import { useLoading, useTheming } from '@/store/state'
|
||||||
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||||
@@ -16,7 +24,7 @@ import { handleError, useNotifications } from '@/store/notifications.js'
|
|||||||
import { command_listener, warning_listener } from '@/helpers/events.js'
|
import { command_listener, warning_listener } from '@/helpers/events.js'
|
||||||
import { MinimizeIcon, MaximizeIcon } from '@/assets/icons'
|
import { MinimizeIcon, MaximizeIcon } from '@/assets/icons'
|
||||||
import { type } from '@tauri-apps/plugin-os'
|
import { type } from '@tauri-apps/plugin-os'
|
||||||
import { isDev, getOS } from '@/helpers/utils.js'
|
import { isDev, getOS, restartApp } from '@/helpers/utils.js'
|
||||||
import { initAnalytics, debugAnalytics, optOutAnalytics, trackEvent } from '@/helpers/analytics'
|
import { initAnalytics, debugAnalytics, optOutAnalytics, trackEvent } from '@/helpers/analytics'
|
||||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||||
import { getVersion } from '@tauri-apps/api/app'
|
import { getVersion } from '@tauri-apps/api/app'
|
||||||
@@ -32,6 +40,9 @@ import { invoke } from '@tauri-apps/api/core'
|
|||||||
import { open } from '@tauri-apps/plugin-shell'
|
import { open } from '@tauri-apps/plugin-shell'
|
||||||
import { get_opening_command, initialize_state } from '@/helpers/state'
|
import { get_opening_command, initialize_state } from '@/helpers/state'
|
||||||
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
||||||
|
import { renderString } from '@modrinth/utils'
|
||||||
|
import { useFetch } from '@/helpers/fetch.js'
|
||||||
|
import { check } from '@tauri-apps/plugin-updater'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
const themeStore = useTheming()
|
||||||
|
|
||||||
@@ -52,6 +63,8 @@ const os = ref('')
|
|||||||
|
|
||||||
const stateInitialized = ref(false)
|
const stateInitialized = ref(false)
|
||||||
|
|
||||||
|
const criticalErrorMessage = ref()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await useCheckDisableMouseover()
|
await useCheckDisableMouseover()
|
||||||
})
|
})
|
||||||
@@ -108,7 +121,18 @@ async function setupApp() {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
useFetch(
|
||||||
|
`https://api.modrinth.com/appCriticalAnnouncement.json?version=${version}`,
|
||||||
|
'criticalAnnouncements',
|
||||||
|
true,
|
||||||
|
).then((res) => {
|
||||||
|
if (res && res.header && res.body) {
|
||||||
|
criticalErrorMessage.value = res
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
get_opening_command().then(handleCommand)
|
get_opening_command().then(handleCommand)
|
||||||
|
checkUpdates()
|
||||||
}
|
}
|
||||||
|
|
||||||
const stateFailed = ref(false)
|
const stateFailed = ref(false)
|
||||||
@@ -218,6 +242,20 @@ async function handleCommand(e) {
|
|||||||
urlModal.value.show(e)
|
urlModal.value.show(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateAvailable = ref(false)
|
||||||
|
async function checkUpdates() {
|
||||||
|
const update = await check()
|
||||||
|
console.log(update)
|
||||||
|
updateAvailable.value = !!update
|
||||||
|
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
checkUpdates()
|
||||||
|
},
|
||||||
|
5 * 1000 * 60,
|
||||||
|
)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -251,6 +289,14 @@ async function handleCommand(e) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings pages-list">
|
<div class="settings pages-list">
|
||||||
|
<button
|
||||||
|
v-if="updateAvailable"
|
||||||
|
v-tooltip="'Install update'"
|
||||||
|
class="btn btn-outline btn-primary icon-only collapsed-button"
|
||||||
|
@click="restartApp()"
|
||||||
|
>
|
||||||
|
<DownloadIcon />
|
||||||
|
</button>
|
||||||
<Button
|
<Button
|
||||||
v-tooltip="'Create profile'"
|
v-tooltip="'Create profile'"
|
||||||
class="sleek-primary collapsed-button"
|
class="sleek-primary collapsed-button"
|
||||||
@@ -266,6 +312,10 @@ async function handleCommand(e) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="view">
|
<div class="view">
|
||||||
|
<div v-if="criticalErrorMessage" class="critical-error-banner" data-tauri-drag-region>
|
||||||
|
<h1>{{ criticalErrorMessage.header }}</h1>
|
||||||
|
<div class="markdown-body" v-html="renderString(criticalErrorMessage.body ?? '')"></div>
|
||||||
|
</div>
|
||||||
<div class="appbar-row">
|
<div class="appbar-row">
|
||||||
<div data-tauri-drag-region class="appbar">
|
<div data-tauri-drag-region class="appbar">
|
||||||
<section class="navigation-controls">
|
<section class="navigation-controls">
|
||||||
@@ -378,6 +428,16 @@ async function handleCommand(e) {
|
|||||||
width: calc(100% - var(--sidebar-width));
|
width: calc(100% - var(--sidebar-width));
|
||||||
background-color: var(--color-raised-bg);
|
background-color: var(--color-raised-bg);
|
||||||
|
|
||||||
|
.critical-error-banner {
|
||||||
|
margin-top: -1.25rem;
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: rgba(203, 34, 69, 0.1);
|
||||||
|
border-left: 2px solid var(--color-red);
|
||||||
|
border-bottom: 2px solid var(--color-red);
|
||||||
|
border-right: 2px solid var(--color-red);
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.appbar {
|
.appbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ import {
|
|||||||
SearchIcon,
|
SearchIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
} from '@modrinth/assets'
|
} from '@modrinth/assets'
|
||||||
import { ConfirmModal, Button, Card, DropdownSelect } from '@modrinth/ui'
|
import { Button, Card, DropdownSelect } from '@modrinth/ui'
|
||||||
import { formatCategoryHeader } from '@modrinth/utils'
|
import { formatCategoryHeader } from '@modrinth/utils'
|
||||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { useTheming } from '@/store/theme.js'
|
|
||||||
import { duplicate, remove } from '@/helpers/profile.js'
|
import { duplicate, remove } from '@/helpers/profile.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
|
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
instances: {
|
instances: {
|
||||||
@@ -35,7 +35,6 @@ const props = defineProps({
|
|||||||
const instanceOptions = ref(null)
|
const instanceOptions = ref(null)
|
||||||
const instanceComponents = ref(null)
|
const instanceComponents = ref(null)
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
const currentDeleteInstance = ref(null)
|
const currentDeleteInstance = ref(null)
|
||||||
const confirmModal = ref(null)
|
const confirmModal = ref(null)
|
||||||
|
|
||||||
@@ -230,13 +229,12 @@ const filteredResults = computed(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<ConfirmModal
|
<ConfirmModalWrapper
|
||||||
ref="confirmModal"
|
ref="confirmModal"
|
||||||
title="Are you sure you want to delete this instance?"
|
title="Are you sure you want to delete this instance?"
|
||||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||||
:has-to-type="false"
|
:has-to-type="false"
|
||||||
proceed-label="Delete"
|
proceed-label="Delete"
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
@proceed="deleteProfile"
|
@proceed="deleteProfile"
|
||||||
/>
|
/>
|
||||||
<Card class="header">
|
<Card class="header">
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
EyeIcon,
|
EyeIcon,
|
||||||
ChevronRightIcon,
|
ChevronRightIcon,
|
||||||
} from '@modrinth/assets'
|
} from '@modrinth/assets'
|
||||||
import { ConfirmModal } from '@modrinth/ui'
|
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||||
import Instance from '@/components/ui/Instance.vue'
|
import Instance from '@/components/ui/Instance.vue'
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||||
@@ -22,7 +22,6 @@ import { handleError } from '@/store/notifications.js'
|
|||||||
import { duplicate, kill, remove, run } from '@/helpers/profile.js'
|
import { duplicate, kill, remove, run } from '@/helpers/profile.js'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||||
import { useTheming } from '@/store/state.js'
|
|
||||||
import { trackEvent } from '@/helpers/analytics'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
import { handleSevereError } from '@/store/error.js'
|
import { handleSevereError } from '@/store/error.js'
|
||||||
import { install as installVersion } from '@/store/install.js'
|
import { install as installVersion } from '@/store/install.js'
|
||||||
@@ -53,7 +52,6 @@ const instanceComponents = ref(null)
|
|||||||
const rows = ref(null)
|
const rows = ref(null)
|
||||||
const deleteConfirmModal = ref(null)
|
const deleteConfirmModal = ref(null)
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
const currentDeleteInstance = ref(null)
|
const currentDeleteInstance = ref(null)
|
||||||
|
|
||||||
async function deleteProfile() {
|
async function deleteProfile() {
|
||||||
@@ -207,13 +205,12 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ConfirmModal
|
<ConfirmModalWrapper
|
||||||
ref="deleteConfirmModal"
|
ref="deleteConfirmModal"
|
||||||
title="Are you sure you want to delete this instance?"
|
title="Are you sure you want to delete this instance?"
|
||||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||||
:has-to-type="false"
|
:has-to-type="false"
|
||||||
proceed-label="Delete"
|
proceed-label="Delete"
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
@proceed="deleteProfile"
|
@proceed="deleteProfile"
|
||||||
/>
|
/>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
v-tooltip.right="'Minecraft accounts'"
|
v-tooltip.right="'Minecraft accounts'"
|
||||||
class="button-base avatar-button"
|
class="button-base avatar-button"
|
||||||
:class="{ expanded: mode === 'expanded' }"
|
:class="{ expanded: mode === 'expanded' }"
|
||||||
@click="showCard = !showCard"
|
@click="toggleMenu"
|
||||||
>
|
>
|
||||||
<Avatar
|
<Avatar
|
||||||
:size="mode === 'expanded' ? 'xs' : 'sm'"
|
:size="mode === 'expanded' ? 'xs' : 'sm'"
|
||||||
@@ -73,6 +73,7 @@ import { handleError } from '@/store/state.js'
|
|||||||
import { trackEvent } from '@/helpers/analytics'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
import { process_listener } from '@/helpers/events'
|
import { process_listener } from '@/helpers/events'
|
||||||
import { handleSevereError } from '@/store/error.js'
|
import { handleSevereError } from '@/store/error.js'
|
||||||
|
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
mode: {
|
mode: {
|
||||||
@@ -144,7 +145,20 @@ const handleClickOutside = (event) => {
|
|||||||
!elements.includes(card.value.$el) &&
|
!elements.includes(card.value.$el) &&
|
||||||
!button.value.contains(event.target)
|
!button.value.contains(event.target)
|
||||||
) {
|
) {
|
||||||
|
toggleMenu(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMenu(override = true) {
|
||||||
|
if (showCard.value || !override) {
|
||||||
|
if (showCard.value) {
|
||||||
|
show_ads_window()
|
||||||
|
}
|
||||||
|
|
||||||
showCard.value = false
|
showCard.value = false
|
||||||
|
} else {
|
||||||
|
hide_ads_window()
|
||||||
|
showCard.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const handleAddContentFromFile = async () => {
|
|||||||
if (!newProject) return
|
if (!newProject) return
|
||||||
|
|
||||||
for (const project of newProject) {
|
for (const project of newProject) {
|
||||||
await add_project_from_path(props.instance.path, project).catch(handleError)
|
await add_project_from_path(props.instance.path, project.path).catch(handleError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||||
|
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
|
||||||
const emit = defineEmits(['menu-closed', 'option-clicked'])
|
const emit = defineEmits(['menu-closed', 'option-clicked'])
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ const shown = ref(false)
|
|||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
showMenu: (event, passedItem, passedOptions) => {
|
showMenu: (event, passedItem, passedOptions) => {
|
||||||
|
hide_ads_window()
|
||||||
item.value = passedItem
|
item.value = passedItem
|
||||||
options.value = passedOptions
|
options.value = passedOptions
|
||||||
|
|
||||||
@@ -69,6 +71,9 @@ const isLinkedData = (item) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const hideContextMenu = () => {
|
const hideContextMenu = () => {
|
||||||
|
if (shown.value) {
|
||||||
|
show_ads_window()
|
||||||
|
}
|
||||||
shown.value = false
|
shown.value = false
|
||||||
emit('menu-closed')
|
emit('menu-closed')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { XIcon, HammerIcon, LogInIcon, UpdatedIcon } from '@modrinth/assets'
|
import { XIcon, HammerIcon, LogInIcon, UpdatedIcon } from '@modrinth/assets'
|
||||||
import { Modal } from '@modrinth/ui'
|
|
||||||
import { ChatIcon } from '@/assets/icons'
|
import { ChatIcon } from '@/assets/icons'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
|
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
|
||||||
@@ -9,6 +8,7 @@ import { handleSevereError } from '@/store/error.js'
|
|||||||
import { cancel_directory_change } from '@/helpers/settings.js'
|
import { cancel_directory_change } from '@/helpers/settings.js'
|
||||||
import { install } from '@/helpers/profile.js'
|
import { install } from '@/helpers/profile.js'
|
||||||
import { trackEvent } from '@/helpers/analytics'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const errorModal = ref()
|
const errorModal = ref()
|
||||||
const error = ref()
|
const error = ref()
|
||||||
@@ -121,7 +121,7 @@ async function repairInstance() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal ref="errorModal" :header="title" :closable="closable">
|
<ModalWrapper ref="errorModal" :header="title" :closable="closable">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="markdown-body">
|
<div class="markdown-body">
|
||||||
<template v-if="errorType === 'minecraft_auth'">
|
<template v-if="errorType === 'minecraft_auth'">
|
||||||
@@ -272,7 +272,7 @@ async function repairInstance() {
|
|||||||
<button v-if="closable" class="btn" @click="errorModal.hide()"><XIcon /> Close</button>
|
<button v-if="closable" class="btn" @click="errorModal.hide()"><XIcon /> Close</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { XIcon, PlusIcon } from '@modrinth/assets'
|
import { XIcon, PlusIcon } from '@modrinth/assets'
|
||||||
import { Button, Checkbox, Modal } from '@modrinth/ui'
|
import { Button, Checkbox } from '@modrinth/ui'
|
||||||
import { PackageIcon, VersionIcon } from '@/assets/icons'
|
import { PackageIcon, VersionIcon } from '@/assets/icons'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { export_profile_mrpack, get_pack_export_candidates } from '@/helpers/profile.js'
|
import { export_profile_mrpack, get_pack_export_candidates } from '@/helpers/profile.js'
|
||||||
import { open } from '@tauri-apps/plugin-dialog'
|
import { open } from '@tauri-apps/plugin-dialog'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { useTheming } from '@/store/theme'
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
instance: {
|
instance: {
|
||||||
@@ -30,8 +30,6 @@ const files = ref([])
|
|||||||
const folders = ref([])
|
const folders = ref([])
|
||||||
const showingFiles = ref(false)
|
const showingFiles = ref(false)
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const initFiles = async () => {
|
const initFiles = async () => {
|
||||||
const newFolders = new Map()
|
const newFolders = new Map()
|
||||||
const sep = '/'
|
const sep = '/'
|
||||||
@@ -106,7 +104,7 @@ const exportPack = async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal ref="exportModal" header="Export modpack" :noblur="!themeStore.advancedRendering">
|
<ModalWrapper ref="exportModal" header="Export modpack">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="labeled_input">
|
<div class="labeled_input">
|
||||||
<p>Modpack Name</p>
|
<p>Modpack Name</p>
|
||||||
@@ -208,7 +206,7 @@ const exportPack = async () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal ref="modal" header="Create instance" :noblur="!themeStore.advancedRendering">
|
<ModalWrapper ref="modal" header="Create instance">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<Chips v-model="creationType" :items="['custom', 'from file', 'import from launcher']" />
|
<Chips v-model="creationType" :items="['custom', 'from file', 'import from launcher']" />
|
||||||
</div>
|
</div>
|
||||||
@@ -193,10 +193,11 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
import {
|
import {
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
UploadIcon,
|
UploadIcon,
|
||||||
@@ -207,7 +208,7 @@ import {
|
|||||||
FolderSearchIcon,
|
FolderSearchIcon,
|
||||||
UpdatedIcon,
|
UpdatedIcon,
|
||||||
} from '@modrinth/assets'
|
} from '@modrinth/assets'
|
||||||
import { Avatar, Button, Chips, Modal, Checkbox } from '@modrinth/ui'
|
import { Avatar, Button, Chips, Checkbox } from '@modrinth/ui'
|
||||||
import { computed, onUnmounted, ref, shallowRef } from 'vue'
|
import { computed, onUnmounted, ref, shallowRef } from 'vue'
|
||||||
import { get_loaders } from '@/helpers/tags'
|
import { get_loaders } from '@/helpers/tags'
|
||||||
import { create } from '@/helpers/profile'
|
import { create } from '@/helpers/profile'
|
||||||
@@ -217,7 +218,6 @@ import { get_game_versions, get_loader_versions } from '@/helpers/metadata'
|
|||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import Multiselect from 'vue-multiselect'
|
import Multiselect from 'vue-multiselect'
|
||||||
import { trackEvent } from '@/helpers/analytics'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
import { useTheming } from '@/store/state.js'
|
|
||||||
import { listen } from '@tauri-apps/api/event'
|
import { listen } from '@tauri-apps/api/event'
|
||||||
import { install_from_file } from '@/helpers/pack.js'
|
import { install_from_file } from '@/helpers/pack.js'
|
||||||
import {
|
import {
|
||||||
@@ -227,8 +227,6 @@ import {
|
|||||||
} from '@/helpers/import.js'
|
} from '@/helpers/import.js'
|
||||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const profile_name = ref('')
|
const profile_name = ref('')
|
||||||
const game_version = ref('')
|
const game_version = ref('')
|
||||||
const loader = ref('vanilla')
|
const loader = ref('vanilla')
|
||||||
@@ -371,7 +369,7 @@ const create_instance = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const upload_icon = async () => {
|
const upload_icon = async () => {
|
||||||
icon.value = await open({
|
const res = await open({
|
||||||
multiple: false,
|
multiple: false,
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
@@ -381,6 +379,8 @@ const upload_icon = async () => {
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
icon.value = res ? res.path : null
|
||||||
|
|
||||||
if (!icon.value) return
|
if (!icon.value) return
|
||||||
display_icon.value = convertFileSrc(icon.value)
|
display_icon.value = convertFileSrc(icon.value)
|
||||||
}
|
}
|
||||||
@@ -417,7 +417,7 @@ const openFile = async () => {
|
|||||||
const newProject = await open({ multiple: false })
|
const newProject = await open({ multiple: false })
|
||||||
if (!newProject) return
|
if (!newProject) return
|
||||||
hide()
|
hide()
|
||||||
await install_from_file(newProject).catch(handleError)
|
await install_from_file(newProject.path).catch(handleError)
|
||||||
|
|
||||||
trackEvent('InstanceCreate', {
|
trackEvent('InstanceCreate', {
|
||||||
source: 'CreationModalFileOpen',
|
source: 'CreationModalFileOpen',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal ref="detectJavaModal" header="Select java version" :noblur="!themeStore.advancedRendering">
|
<ModalWrapper ref="detectJavaModal" header="Select java version">
|
||||||
<div class="auto-detect-modal">
|
<div class="auto-detect-modal">
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div class="table-row table-head">
|
<div class="table-row table-head">
|
||||||
@@ -32,18 +32,16 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { PlusIcon, CheckIcon, XIcon } from '@modrinth/assets'
|
import { PlusIcon, CheckIcon, XIcon } from '@modrinth/assets'
|
||||||
import { Modal, Button } from '@modrinth/ui'
|
import { Button } from '@modrinth/ui'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { find_filtered_jres } from '@/helpers/jre.js'
|
import { find_filtered_jres } from '@/helpers/jre.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { useTheming } from '@/store/theme.js'
|
|
||||||
import { trackEvent } from '@/helpers/analytics'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const chosenInstallOptions = ref([])
|
const chosenInstallOptions = ref([])
|
||||||
const detectJavaModal = ref(null)
|
const detectJavaModal = ref(null)
|
||||||
|
|||||||
@@ -127,17 +127,17 @@ async function handleJavaFileInput() {
|
|||||||
let filePath = await open()
|
let filePath = await open()
|
||||||
|
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
let result = await get_jre(filePath)
|
let result = await get_jre(filePath.path)
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = {
|
result = {
|
||||||
path: filePath,
|
path: filePath.path,
|
||||||
version: props.version.toString(),
|
version: props.version.toString(),
|
||||||
architecture: 'x86',
|
architecture: 'x86',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trackEvent('JavaManualSelect', {
|
trackEvent('JavaManualSelect', {
|
||||||
path: filePath,
|
path: filePath.path,
|
||||||
version: props.version,
|
version: props.version,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { CheckIcon } from '@modrinth/assets'
|
import { CheckIcon } from '@modrinth/assets'
|
||||||
import { Button, Modal, Badge } from '@modrinth/ui'
|
import { Button, Badge } from '@modrinth/ui'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useTheming } from '@/store/theme'
|
|
||||||
import { update_managed_modrinth_version } from '@/helpers/profile'
|
import { update_managed_modrinth_version } from '@/helpers/profile'
|
||||||
import { releaseColor } from '@/helpers/utils'
|
import { releaseColor } from '@/helpers/utils'
|
||||||
import { SwapIcon } from '@/assets/icons/index.js'
|
import { SwapIcon } from '@/assets/icons/index.js'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
versions: {
|
versions: {
|
||||||
@@ -33,8 +33,6 @@ const installedVersion = computed(() => props.instance?.linked_data?.version_id)
|
|||||||
const installing = computed(() => props.instance.install_stage !== 'installed')
|
const installing = computed(() => props.instance.install_stage !== 'installed')
|
||||||
const inProgress = ref(false)
|
const inProgress = ref(false)
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const switchVersion = async (versionId) => {
|
const switchVersion = async (versionId) => {
|
||||||
inProgress.value = true
|
inProgress.value = true
|
||||||
await update_managed_modrinth_version(props.instance.path, versionId)
|
await update_managed_modrinth_version(props.instance.path, versionId)
|
||||||
@@ -43,11 +41,10 @@ const switchVersion = async (versionId) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<ModalWrapper
|
||||||
ref="modpackVersionModal"
|
ref="modpackVersionModal"
|
||||||
class="modpack-version-modal"
|
class="modpack-version-modal"
|
||||||
header="Change modpack version"
|
header="Change modpack version"
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
>
|
>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<Card v-if="instance.linked_data" class="mod-card">
|
<Card v-if="instance.linked_data" class="mod-card">
|
||||||
@@ -111,7 +108,7 @@ const switchVersion = async (versionId) => {
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -32,26 +32,26 @@ let intersectionObserver
|
|||||||
let mutationObserver
|
let mutationObserver
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (showAd.value) {
|
if (showAd.value) {
|
||||||
updateAdPosition()
|
updateAdPosition(true)
|
||||||
|
|
||||||
resizeObserver = new ResizeObserver(updateAdPosition)
|
resizeObserver = new ResizeObserver(() => updateAdPosition())
|
||||||
resizeObserver.observe(adsWrapper.value)
|
resizeObserver.observe(adsWrapper.value)
|
||||||
|
|
||||||
intersectionObserver = new IntersectionObserver(updateAdPosition)
|
intersectionObserver = new IntersectionObserver(() => updateAdPosition())
|
||||||
intersectionObserver.observe(adsWrapper.value)
|
intersectionObserver.observe(adsWrapper.value)
|
||||||
|
|
||||||
mutationObserver = new MutationObserver(updateAdPosition)
|
mutationObserver = new MutationObserver(() => updateAdPosition())
|
||||||
mutationObserver.observe(adsWrapper.value, { attributes: true, childList: true, subtree: true })
|
mutationObserver.observe(adsWrapper.value, { attributes: true, childList: true, subtree: true })
|
||||||
|
|
||||||
// Add scroll event listener
|
// Add scroll event listener
|
||||||
scrollHandler = () => {
|
scrollHandler = () => {
|
||||||
requestAnimationFrame(updateAdPosition)
|
requestAnimationFrame(() => updateAdPosition())
|
||||||
}
|
}
|
||||||
window.addEventListener('scroll', scrollHandler, { passive: true })
|
window.addEventListener('scroll', scrollHandler, { passive: true })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function updateAdPosition() {
|
function updateAdPosition(overrideShown = false) {
|
||||||
if (adsWrapper.value) {
|
if (adsWrapper.value) {
|
||||||
const rect = adsWrapper.value.getBoundingClientRect()
|
const rect = adsWrapper.value.getBoundingClientRect()
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ function updateAdPosition() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init_ads_window(rect.left + window.scrollX, y, rect.right - rect.left, height)
|
init_ads_window(rect.left + window.scrollX, y, rect.right - rect.left, height, overrideShown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,9 +130,16 @@ const os = ref('')
|
|||||||
getOS().then((x) => (os.value = x))
|
getOS().then((x) => (os.value = x))
|
||||||
|
|
||||||
loading_listener(async (e) => {
|
loading_listener(async (e) => {
|
||||||
|
console.log(e)
|
||||||
if (e.event.type === 'directory_move') {
|
if (e.event.type === 'directory_move') {
|
||||||
loadingProgress.value = 100 * (e.fraction ?? 1)
|
loadingProgress.value = 100 * (e.fraction ?? 1)
|
||||||
message.value = 'Updating app directory...'
|
message.value = 'Updating app directory...'
|
||||||
|
} else if (e.event.type === 'launcher_update') {
|
||||||
|
loadingProgress.value = 100 * (e.fraction ?? 1)
|
||||||
|
message.value = 'Updating Modrinth App...'
|
||||||
|
} else if (e.event.type === 'checking_for_updates') {
|
||||||
|
loadingProgress.value = 100 * (e.fraction ?? 1)
|
||||||
|
message.value = 'Checking for updates...'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Modal, Button } from '@modrinth/ui'
|
import { Button } from '@modrinth/ui'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import SearchCard from '@/components/ui/SearchCard.vue'
|
import SearchCard from '@/components/ui/SearchCard.vue'
|
||||||
import { get_categories } from '@/helpers/tags.js'
|
import { get_categories } from '@/helpers/tags.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { get_version, get_project } from '@/helpers/cache.js'
|
import { get_version, get_project } from '@/helpers/cache.js'
|
||||||
import { install as installVersion } from '@/store/install.js'
|
import { install as installVersion } from '@/store/install.js'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const confirmModal = ref(null)
|
const confirmModal = ref(null)
|
||||||
const project = ref(null)
|
const project = ref(null)
|
||||||
@@ -41,7 +42,7 @@ async function install() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal ref="confirmModal" :header="`Install ${project?.title}`">
|
<ModalWrapper ref="confirmModal" :header="`Install ${project?.title}`">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<SearchCard
|
<SearchCard
|
||||||
:project="project"
|
:project="project"
|
||||||
@@ -60,7 +61,7 @@ async function install() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<Modal
|
<ModalWrapper ref="incompatibleModal" header="Incompatibility warning" :on-hide="onInstall">
|
||||||
ref="incompatibleModal"
|
|
||||||
header="Incompatibility warning"
|
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
:on-hide="onInstall"
|
|
||||||
>
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>
|
<p>
|
||||||
This {{ versions?.length > 0 ? 'project' : 'version' }} is not compatible with the instance
|
This {{ versions?.length > 0 ? 'project' : 'version' }} is not compatible with the instance
|
||||||
@@ -51,20 +46,19 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
import { XIcon, DownloadIcon } from '@modrinth/assets'
|
import { XIcon, DownloadIcon } from '@modrinth/assets'
|
||||||
import { Button, Modal, DropdownSelect } from '@modrinth/ui'
|
import { Button, DropdownSelect } from '@modrinth/ui'
|
||||||
import { formatCategory } from '@modrinth/utils'
|
import { formatCategory } from '@modrinth/utils'
|
||||||
import { add_project_from_version as installMod } from '@/helpers/profile'
|
import { add_project_from_version as installMod } from '@/helpers/profile'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { handleError, useTheming } from '@/store/state.js'
|
import { handleError } from '@/store/state.js'
|
||||||
import { trackEvent } from '@/helpers/analytics'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const instance = ref(null)
|
const instance = ref(null)
|
||||||
const project = ref(null)
|
const project = ref(null)
|
||||||
const versions = ref(null)
|
const versions = ref(null)
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { XIcon, DownloadIcon } from '@modrinth/assets'
|
import { XIcon, DownloadIcon } from '@modrinth/assets'
|
||||||
import { Button, Modal } from '@modrinth/ui'
|
import { Button } from '@modrinth/ui'
|
||||||
import { install as pack_install } from '@/helpers/pack'
|
import { install as pack_install } from '@/helpers/pack'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { trackEvent } from '@/helpers/analytics'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
import { useTheming } from '@/store/theme.js'
|
|
||||||
import { handleError } from '@/store/state.js'
|
import { handleError } from '@/store/state.js'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const versionId = ref()
|
const versionId = ref()
|
||||||
const project = ref()
|
const project = ref()
|
||||||
@@ -52,12 +50,7 @@ async function install() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<ModalWrapper ref="confirmModal" header="Are you sure?" :on-hide="onInstall">
|
||||||
ref="confirmModal"
|
|
||||||
header="Are you sure?"
|
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
:on-hide="onInstall"
|
|
||||||
>
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>You already have this modpack installed. Are you sure you want to install it again?</p>
|
<p>You already have this modpack installed. Are you sure you want to install it again?</p>
|
||||||
<div class="input-group push-right">
|
<div class="input-group push-right">
|
||||||
@@ -67,7 +60,7 @@ async function install() {
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
RightArrowIcon,
|
RightArrowIcon,
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
} from '@modrinth/assets'
|
} from '@modrinth/assets'
|
||||||
import { Avatar, Modal, Button, Card } from '@modrinth/ui'
|
import { Avatar, Button, Card } from '@modrinth/ui'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import {
|
import {
|
||||||
add_project_from_version as installMod,
|
add_project_from_version as installMod,
|
||||||
@@ -19,12 +19,11 @@ import {
|
|||||||
import { open } from '@tauri-apps/plugin-dialog'
|
import { open } from '@tauri-apps/plugin-dialog'
|
||||||
import { installVersionDependencies } from '@/store/install.js'
|
import { installVersionDependencies } from '@/store/install.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { useTheming } from '@/store/theme.js'
|
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||||
import { trackEvent } from '@/helpers/analytics'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const versions = ref()
|
const versions = ref()
|
||||||
@@ -142,7 +141,7 @@ const toggleCreation = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const upload_icon = async () => {
|
const upload_icon = async () => {
|
||||||
icon.value = await open({
|
const res = await open({
|
||||||
multiple: false,
|
multiple: false,
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
@@ -151,6 +150,7 @@ const upload_icon = async () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
icon.value = res ? res.path : null
|
||||||
|
|
||||||
if (!icon.value) return
|
if (!icon.value) return
|
||||||
display_icon.value = convertFileSrc(icon.value)
|
display_icon.value = convertFileSrc(icon.value)
|
||||||
@@ -213,12 +213,7 @@ const createInstance = async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal
|
<ModalWrapper ref="installModal" header="Install project to instance" :on-hide="onInstall">
|
||||||
ref="installModal"
|
|
||||||
header="Install project to instance"
|
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
:on-hide="onInstall"
|
|
||||||
>
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<input
|
<input
|
||||||
v-model="searchFilter"
|
v-model="searchFilter"
|
||||||
@@ -304,7 +299,7 @@ const createInstance = async () => {
|
|||||||
<Button @click="installModal.hide()">Cancel</Button>
|
<Button @click="installModal.hide()">Cancel</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { ConfirmModal } from '@modrinth/ui'
|
||||||
|
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
import { useTheming } from '@/store/theme.js'
|
||||||
|
|
||||||
|
const themeStore = useTheming()
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
confirmationText: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
hasToType: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: 'No title defined',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: 'No description defined',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
proceedLabel: {
|
||||||
|
type: String,
|
||||||
|
default: 'Proceed',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['proceed'])
|
||||||
|
const modal = ref(null)
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show: () => {
|
||||||
|
hide_ads_window()
|
||||||
|
modal.value.show()
|
||||||
|
},
|
||||||
|
hide: () => {
|
||||||
|
onModalHide()
|
||||||
|
modal.value.hide()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
function onModalHide() {
|
||||||
|
show_ads_window()
|
||||||
|
}
|
||||||
|
|
||||||
|
function proceed() {
|
||||||
|
emit('proceed')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ConfirmModal
|
||||||
|
ref="modal"
|
||||||
|
:confirmation-text="confirmationText"
|
||||||
|
:has-to-type="hasToType"
|
||||||
|
:title="title"
|
||||||
|
:description="description"
|
||||||
|
:proceed-label="proceedLabel"
|
||||||
|
:on-hide="onModalHide"
|
||||||
|
:noblur="!themeStore.advancedRendering"
|
||||||
|
@proceed="proceed"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
49
apps/app-frontend/src/components/ui/modal/ModalWrapper.vue
Normal file
49
apps/app-frontend/src/components/ui/modal/ModalWrapper.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Modal } from '@modrinth/ui'
|
||||||
|
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
import { useTheming } from '@/store/theme.js'
|
||||||
|
|
||||||
|
const themeStore = useTheming()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
header: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
closable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
onHide: {
|
||||||
|
type: Function,
|
||||||
|
default() {
|
||||||
|
return () => {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const modal = ref(null)
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show: () => {
|
||||||
|
hide_ads_window()
|
||||||
|
modal.value.show()
|
||||||
|
},
|
||||||
|
hide: () => {
|
||||||
|
onModalHide()
|
||||||
|
modal.value.hide()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
function onModalHide() {
|
||||||
|
show_ads_window()
|
||||||
|
props.onHide()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal ref="modal" :header="header" :noblur="!themeStore.advancedRendering" @hide="onModalHide">
|
||||||
|
<slot />
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { ShareModal } from '@modrinth/ui'
|
||||||
|
import { show_ads_window, hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
import { useTheming } from '@/store/theme.js'
|
||||||
|
|
||||||
|
const themeStore = useTheming()
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
header: {
|
||||||
|
type: String,
|
||||||
|
default: 'Share',
|
||||||
|
},
|
||||||
|
shareTitle: {
|
||||||
|
type: String,
|
||||||
|
default: 'Modrinth',
|
||||||
|
},
|
||||||
|
shareText: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
link: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
openInNewTab: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const modal = ref(null)
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show: (passedContent) => {
|
||||||
|
hide_ads_window()
|
||||||
|
modal.value.show(passedContent)
|
||||||
|
},
|
||||||
|
hide: () => {
|
||||||
|
onModalHide()
|
||||||
|
modal.value.hide()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
function onModalHide() {
|
||||||
|
show_ads_window()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ShareModal
|
||||||
|
ref="modal"
|
||||||
|
:header="header"
|
||||||
|
:share-title="shareTitle"
|
||||||
|
:share-text="shareText"
|
||||||
|
:link="link"
|
||||||
|
:open-in-new-tab="openInNewTab"
|
||||||
|
:on-hide="onModalHide"
|
||||||
|
:noblur="!themeStore.advancedRendering"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { UserIcon, LockIcon, MailIcon } from '@modrinth/assets'
|
import { UserIcon, LockIcon, MailIcon } from '@modrinth/assets'
|
||||||
import { Button, Card, Checkbox, Modal } from '@modrinth/ui'
|
import { Button, Card, Checkbox } from '@modrinth/ui'
|
||||||
import {
|
import {
|
||||||
DiscordIcon,
|
DiscordIcon,
|
||||||
GithubIcon,
|
GithubIcon,
|
||||||
@@ -13,6 +13,7 @@ import { login, login_2fa, create_account, login_pass } from '@/helpers/mr_auth.
|
|||||||
import { handleError, useNotifications } from '@/store/state.js'
|
import { handleError, useNotifications } from '@/store/state.js'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { handleSevereError } from '@/store/error.js'
|
import { handleSevereError } from '@/store/error.js'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
callback: {
|
callback: {
|
||||||
@@ -132,7 +133,7 @@ async function createAccount() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal ref="modal" :on-hide="removeWidget">
|
<ModalWrapper ref="modal" :on-hide="removeWidget">
|
||||||
<Card>
|
<Card>
|
||||||
<template v-if="twoFactorFlow">
|
<template v-if="twoFactorFlow">
|
||||||
<h1>Enter two-factor code</h1>
|
<h1>Enter two-factor code</h1>
|
||||||
@@ -217,17 +218,17 @@ async function createAccount() {
|
|||||||
v-else-if="loggingIn"
|
v-else-if="loggingIn"
|
||||||
color="primary"
|
color="primary"
|
||||||
large
|
large
|
||||||
@click="signIn"
|
|
||||||
:disabled="!turnstileToken"
|
:disabled="!turnstileToken"
|
||||||
|
@click="signIn"
|
||||||
>
|
>
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-else color="primary" large @click="createAccount" :disabled="!turnstileToken">
|
<Button v-else color="primary" large :disabled="!turnstileToken" @click="createAccount">
|
||||||
Create account
|
Create account
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import { invoke } from '@tauri-apps/api/core'
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
|
||||||
export async function init_ads_window(x, y, width, height) {
|
export async function init_ads_window(x, y, width, height, overrideShown = false) {
|
||||||
return await invoke('plugin:ads|init_ads_window', { x, y, width, height })
|
return await invoke('plugin:ads|init_ads_window', { x, y, width, height, overrideShown })
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function hide_ads_window() {
|
export async function show_ads_window() {
|
||||||
return await invoke('plugin:ads|hide_ads_window')
|
return await invoke('plugin:ads|show_ads_window')
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function hide_ads_window(reset) {
|
||||||
|
return await invoke('plugin:ads|hide_ads_window', { reset })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ export async function highlightModInProfile(profilePath, projectPath) {
|
|||||||
return await highlightInFolder(fullPath)
|
return await highlightInFolder(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function restartApp() {
|
||||||
|
return await invoke('restart_app')
|
||||||
|
}
|
||||||
|
|
||||||
export const releaseColor = (releaseType) => {
|
export const releaseColor = (releaseType) => {
|
||||||
switch (releaseType) {
|
switch (releaseType) {
|
||||||
case 'release':
|
case 'release':
|
||||||
|
|||||||
@@ -884,6 +884,7 @@ const isModProject = computed(() => ['modpack', 'mod'].includes(projectType.valu
|
|||||||
height: fit-content;
|
height: fit-content;
|
||||||
min-height: calc(100vh - 3.25rem);
|
min-height: calc(100vh - 3.25rem);
|
||||||
max-height: calc(100vh - 3.25rem);
|
max-height: calc(100vh - 3.25rem);
|
||||||
|
width: 20rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
@@ -902,8 +903,8 @@ const isModProject = computed(() => ['modpack', 'mod'].includes(projectType.valu
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
margin: 0 1rem 0.5rem calc(300px + 2.5rem);
|
margin: 0 1rem 0.5rem calc(20rem + 1rem);
|
||||||
width: calc(100% - calc(300px + 2.5rem));
|
width: calc(100% - calc(20rem + 1rem));
|
||||||
|
|
||||||
.offline {
|
.offline {
|
||||||
margin: 1rem;
|
margin: 1rem;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { get_search_results } from '@/helpers/cache.js'
|
|||||||
import { hide_ads_window } from '@/helpers/ads.js'
|
import { hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
hide_ads_window()
|
hide_ads_window(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
const featuredModpacks = ref({})
|
const featuredModpacks = ref({})
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { NewInstanceImage } from '@/assets/icons'
|
|||||||
import { hide_ads_window } from '@/helpers/ads.js'
|
import { hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
hide_ads_window()
|
hide_ads_window(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, onMounted } from 'vue'
|
import { ref, watch, onMounted } from 'vue'
|
||||||
import { LogOutIcon, LogInIcon, BoxIcon, FolderSearchIcon, TrashIcon } from '@modrinth/assets'
|
import { LogOutIcon, LogInIcon, BoxIcon, FolderSearchIcon, TrashIcon } from '@modrinth/assets'
|
||||||
import { Card, Slider, DropdownSelect, Toggle, ConfirmModal, Button } from '@modrinth/ui'
|
import { Card, Slider, DropdownSelect, Toggle, Button } from '@modrinth/ui'
|
||||||
import { handleError, useTheming } from '@/store/state'
|
import { handleError, useTheming } from '@/store/state'
|
||||||
import { get, set } from '@/helpers/settings'
|
import { get, set } from '@/helpers/settings'
|
||||||
import { get_java_versions, get_max_memory, set_java_version } from '@/helpers/jre'
|
import { get_java_versions, get_max_memory, set_java_version } from '@/helpers/jre'
|
||||||
@@ -14,6 +14,7 @@ import { getOS } from '@/helpers/utils.js'
|
|||||||
import { getVersion } from '@tauri-apps/api/app'
|
import { getVersion } from '@tauri-apps/api/app'
|
||||||
import { get_user, purge_cache_types } from '@/helpers/cache.js'
|
import { get_user, purge_cache_types } from '@/helpers/cache.js'
|
||||||
import { hide_ads_window } from '@/helpers/ads.js'
|
import { hide_ads_window } from '@/helpers/ads.js'
|
||||||
|
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
hide_ads_window()
|
hide_ads_window()
|
||||||
@@ -174,13 +175,12 @@ async function purgeCache() {
|
|||||||
Sign in
|
Sign in
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ConfirmModal
|
<ConfirmModalWrapper
|
||||||
ref="purgeCacheConfirmModal"
|
ref="purgeCacheConfirmModal"
|
||||||
title="Are you sure you want to purge the cache?"
|
title="Are you sure you want to purge the cache?"
|
||||||
description="If you proceed, your entire cache will be purged. This may slow down the app temporarily."
|
description="If you proceed, your entire cache will be purged. This may slow down the app temporarily."
|
||||||
:has-to-type="false"
|
:has-to-type="false"
|
||||||
proceed-label="Purge cache"
|
proceed-label="Purge cache"
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
@proceed="purgeCache"
|
@proceed="purgeCache"
|
||||||
/>
|
/>
|
||||||
<div class="adjacent-input">
|
<div class="adjacent-input">
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</RecycleScroller>
|
</RecycleScroller>
|
||||||
</div>
|
</div>
|
||||||
<ShareModal
|
<ShareModalWrapper
|
||||||
ref="shareModal"
|
ref="shareModal"
|
||||||
header="Share Log"
|
header="Share Log"
|
||||||
share-title="Instance Log"
|
share-title="Instance Log"
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { CheckIcon, ClipboardCopyIcon, ShareIcon, TrashIcon } from '@modrinth/assets'
|
import { CheckIcon, ClipboardCopyIcon, ShareIcon, TrashIcon } from '@modrinth/assets'
|
||||||
import { Button, Card, ShareModal, Checkbox, DropdownSelect } from '@modrinth/ui'
|
import { Button, Card, Checkbox, DropdownSelect } from '@modrinth/ui'
|
||||||
import {
|
import {
|
||||||
delete_logs_by_filename,
|
delete_logs_by_filename,
|
||||||
get_logs,
|
get_logs,
|
||||||
@@ -107,6 +107,7 @@ import { handleError } from '@/store/notifications.js'
|
|||||||
import { ofetch } from 'ofetch'
|
import { ofetch } from 'ofetch'
|
||||||
import { RecycleScroller } from 'vue-virtual-scroller'
|
import { RecycleScroller } from 'vue-virtual-scroller'
|
||||||
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
||||||
|
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
|
||||||
|
|
||||||
dayjs.extend(isToday)
|
dayjs.extend(isToday)
|
||||||
dayjs.extend(isYesterday)
|
dayjs.extend(isYesterday)
|
||||||
|
|||||||
@@ -284,7 +284,7 @@
|
|||||||
:link-function="(page) => `?page=${page}`"
|
:link-function="(page) => `?page=${page}`"
|
||||||
@switch-page="switchPage"
|
@switch-page="switchPage"
|
||||||
/>
|
/>
|
||||||
<Modal ref="deleteWarning" header="Are you sure?">
|
<ModalWrapper ref="deleteWarning" header="Are you sure?">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="markdown-body">
|
<div class="markdown-body">
|
||||||
<p>
|
<p>
|
||||||
@@ -302,8 +302,8 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
<Modal ref="deleteDisabledWarning" header="Are you sure?">
|
<ModalWrapper ref="deleteDisabledWarning" header="Are you sure?">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="markdown-body">
|
<div class="markdown-body">
|
||||||
<p>
|
<p>
|
||||||
@@ -325,8 +325,8 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
<ShareModal
|
<ShareModalWrapper
|
||||||
ref="shareModal"
|
ref="shareModal"
|
||||||
share-title="Sharing modpack content"
|
share-title="Sharing modpack content"
|
||||||
share-text="Check out the projects I'm using in my modpack!"
|
share-text="Check out the projects I'm using in my modpack!"
|
||||||
@@ -360,8 +360,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
Pagination,
|
Pagination,
|
||||||
DropdownSelect,
|
DropdownSelect,
|
||||||
ShareModal,
|
|
||||||
Modal,
|
|
||||||
Checkbox,
|
Checkbox,
|
||||||
AnimatedLogo,
|
AnimatedLogo,
|
||||||
Avatar,
|
Avatar,
|
||||||
@@ -393,6 +391,8 @@ import {
|
|||||||
get_version_many,
|
get_version_many,
|
||||||
} from '@/helpers/cache.js'
|
} from '@/helpers/cache.js'
|
||||||
import { profile_listener } from '@/helpers/events.js'
|
import { profile_listener } from '@/helpers/events.js'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
instance: {
|
instance: {
|
||||||
@@ -784,6 +784,7 @@ const deleteDisabled = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const shareNames = async () => {
|
const shareNames = async () => {
|
||||||
|
console.log(functionValues.value)
|
||||||
await shareModal.value.show(functionValues.value.map((x) => x.name).join('\n'))
|
await shareModal.value.show(functionValues.value.map((x) => x.name).join('\n'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<ConfirmModal
|
<ConfirmModalWrapper
|
||||||
ref="modal_confirm"
|
ref="modal_confirm"
|
||||||
title="Are you sure you want to delete this instance?"
|
title="Are you sure you want to delete this instance?"
|
||||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||||
:has-to-type="false"
|
:has-to-type="false"
|
||||||
proceed-label="Delete"
|
proceed-label="Delete"
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
@proceed="removeProfile"
|
@proceed="removeProfile"
|
||||||
/>
|
/>
|
||||||
<Modal
|
<ModalWrapper ref="modalConfirmUnlock" header="Are you sure you want to unlock this instance?">
|
||||||
ref="modalConfirmUnlock"
|
|
||||||
header="Are you sure you want to unlock this instance?"
|
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
>
|
|
||||||
<div class="modal-delete">
|
<div class="modal-delete">
|
||||||
<div
|
<div
|
||||||
class="markdown-body"
|
class="markdown-body"
|
||||||
@@ -31,13 +26,9 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
|
|
||||||
<Modal
|
<ModalWrapper ref="modalConfirmUnpair" header="Are you sure you want to unpair this instance?">
|
||||||
ref="modalConfirmUnpair"
|
|
||||||
header="Are you sure you want to unpair this instance?"
|
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
>
|
|
||||||
<div class="modal-delete">
|
<div class="modal-delete">
|
||||||
<div
|
<div
|
||||||
class="markdown-body"
|
class="markdown-body"
|
||||||
@@ -56,13 +47,9 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
|
|
||||||
<Modal
|
<ModalWrapper ref="changeVersionsModal" header="Change instance versions">
|
||||||
ref="changeVersionsModal"
|
|
||||||
header="Change instance versions"
|
|
||||||
:noblur="!themeStore.advancedRendering"
|
|
||||||
>
|
|
||||||
<div class="change-versions-modal universal-body">
|
<div class="change-versions-modal universal-body">
|
||||||
<div class="input-row">
|
<div class="input-row">
|
||||||
<p class="input-label">Loader</p>
|
<p class="input-label">Loader</p>
|
||||||
@@ -106,7 +93,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</ModalWrapper>
|
||||||
<section class="card">
|
<section class="card">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
<h3>
|
<h3>
|
||||||
@@ -511,18 +498,7 @@ import {
|
|||||||
DownloadIcon,
|
DownloadIcon,
|
||||||
ClipboardCopyIcon,
|
ClipboardCopyIcon,
|
||||||
} from '@modrinth/assets'
|
} from '@modrinth/assets'
|
||||||
import {
|
import { Button, Toggle, Card, Slider, Checkbox, Avatar, Chips, DropdownSelect } from '@modrinth/ui'
|
||||||
Button,
|
|
||||||
Toggle,
|
|
||||||
ConfirmModal,
|
|
||||||
Card,
|
|
||||||
Slider,
|
|
||||||
Checkbox,
|
|
||||||
Avatar,
|
|
||||||
Modal,
|
|
||||||
Chips,
|
|
||||||
DropdownSelect,
|
|
||||||
} from '@modrinth/ui'
|
|
||||||
import { SwapIcon } from '@/assets/icons'
|
import { SwapIcon } from '@/assets/icons'
|
||||||
|
|
||||||
import { Multiselect } from 'vue-multiselect'
|
import { Multiselect } from 'vue-multiselect'
|
||||||
@@ -546,10 +522,11 @@ import { open } from '@tauri-apps/plugin-dialog'
|
|||||||
import { get_loader_versions } from '@/helpers/metadata.js'
|
import { get_loader_versions } from '@/helpers/metadata.js'
|
||||||
import { get_game_versions, get_loaders } from '@/helpers/tags.js'
|
import { get_game_versions, get_loaders } from '@/helpers/tags.js'
|
||||||
import { handleError } from '@/store/notifications.js'
|
import { handleError } from '@/store/notifications.js'
|
||||||
import { useTheming } from '@/store/theme.js'
|
|
||||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||||
import ModpackVersionModal from '@/components/ui/ModpackVersionModal.vue'
|
import ModpackVersionModal from '@/components/ui/ModpackVersionModal.vue'
|
||||||
import { trackEvent } from '@/helpers/analytics'
|
import { trackEvent } from '@/helpers/analytics'
|
||||||
|
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||||
|
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||||
|
|
||||||
const breadcrumbs = useBreadcrumbs()
|
const breadcrumbs = useBreadcrumbs()
|
||||||
|
|
||||||
@@ -570,8 +547,6 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const themeStore = useTheming()
|
|
||||||
|
|
||||||
const title = ref(props.instance.name)
|
const title = ref(props.instance.name)
|
||||||
const icon = ref(props.instance.icon_path)
|
const icon = ref(props.instance.icon_path)
|
||||||
const groups = ref(props.instance.groups)
|
const groups = ref(props.instance.groups)
|
||||||
@@ -606,7 +581,7 @@ async function setIcon() {
|
|||||||
|
|
||||||
if (!value) return
|
if (!value) return
|
||||||
|
|
||||||
icon.value = value
|
icon.value = value.path
|
||||||
await edit_icon(props.instance.path, icon.value).catch(handleError)
|
await edit_icon(props.instance.path, icon.value).catch(handleError)
|
||||||
|
|
||||||
trackEvent('InstanceSetIcon')
|
trackEvent('InstanceSetIcon')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "theseus_gui"
|
name = "theseus_gui"
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
description = "The Modrinth App is a desktop application for managing your Minecraft mods"
|
description = "The Modrinth App is a desktop application for managing your Minecraft mods"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
repository = "https://github.com/modrinth/code/apps/app/"
|
repository = "https://github.com/modrinth/code/apps/app/"
|
||||||
@@ -22,7 +22,8 @@ tauri-plugin-deep-link = "2.0.0-rc"
|
|||||||
tauri-plugin-os = "2.0.0-rc"
|
tauri-plugin-os = "2.0.0-rc"
|
||||||
tauri-plugin-shell = "2.0.0-rc"
|
tauri-plugin-shell = "2.0.0-rc"
|
||||||
tauri-plugin-dialog = "2.0.0-rc"
|
tauri-plugin-dialog = "2.0.0-rc"
|
||||||
tauri-plugin-updater = { version = "2.0.0-rc.1", optional = true }
|
tauri-plugin-updater = { version = "2.0.0-rc" }
|
||||||
|
tauri-plugin-single-instance = { version = "2.0.0-rc" }
|
||||||
|
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
@@ -67,4 +68,4 @@ default = ["custom-protocol"]
|
|||||||
# this feature is used for production builds where `devPath` points to the filesystem
|
# this feature is used for production builds where `devPath` points to the filesystem
|
||||||
# DO NOT remove this
|
# DO NOT remove this
|
||||||
custom-protocol = ["tauri/custom-protocol"]
|
custom-protocol = ["tauri/custom-protocol"]
|
||||||
updater = ["dep:tauri-plugin-updater"]
|
updater = []
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ fn main() {
|
|||||||
InlinedPlugin::new()
|
InlinedPlugin::new()
|
||||||
.commands(&[
|
.commands(&[
|
||||||
"get_java_versions",
|
"get_java_versions",
|
||||||
"set_java_versions",
|
"set_java_version",
|
||||||
"jre_find_filtered_jres",
|
"jre_find_filtered_jres",
|
||||||
"jre_get_jre",
|
"jre_get_jre",
|
||||||
"jre_test_jre",
|
"jre_test_jre",
|
||||||
@@ -225,6 +225,7 @@ fn main() {
|
|||||||
"init_ads_window",
|
"init_ads_window",
|
||||||
"hide_ads_window",
|
"hide_ads_window",
|
||||||
"scroll_ads_window",
|
"scroll_ads_window",
|
||||||
|
"show_ads_window",
|
||||||
])
|
])
|
||||||
.default_permission(
|
.default_permission(
|
||||||
DefaultPermissionRule::AllowAllCommands,
|
DefaultPermissionRule::AllowAllCommands,
|
||||||
|
|||||||
@@ -38,4 +38,4 @@
|
|||||||
"utils:default",
|
"utils:default",
|
||||||
"ads:default"
|
"ads:default"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
11
apps/app/capabilities/updater.json
Normal file
11
apps/app/capabilities/updater.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"identifier": "updater",
|
||||||
|
"description": "",
|
||||||
|
"local": true,
|
||||||
|
"windows": [
|
||||||
|
"main"
|
||||||
|
],
|
||||||
|
"permissions": [
|
||||||
|
"updater:default"
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
{"ads":{"identifier":"ads","description":"","remote":{"urls":["https://modrinth.com/*","http://localhost:3000/*"]},"local":false,"webviews":["ads-window"],"permissions":["shell:allow-open","ads:default"]},"core":{"identifier":"core","description":"","local":true,"windows":["main"],"permissions":["core:default","core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","core:window:allow-create","core:window:allow-maximize","core:window:allow-toggle-maximize","core:window:allow-unmaximize","core:window:allow-minimize","core:window:allow-unminimize","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-set-decorations","core:window:allow-start-dragging","core:webview:allow-set-webview-zoom"]},"plugins":{"identifier":"plugins","description":"","local":true,"windows":["main"],"permissions":["dialog:allow-open","dialog:allow-confirm","shell:allow-open","os:allow-platform","os:allow-version","os:allow-os-type","os:allow-family","os:allow-arch","os:allow-exe-extension","os:allow-locale","os:allow-hostname","deep-link:default","window-state:default","window-state:allow-restore-state","window-state:allow-save-window-state","auth:default","import:default","jre:default","logs:default","metadata:default","mr-auth:default","profile-create:default","pack:default","process:default","profile:default","cache:default","settings:default","tags:default","utils:default","ads:default"]}}
|
{"ads":{"identifier":"ads","description":"","remote":{"urls":["https://modrinth.com/*","http://localhost:3000/*"]},"local":false,"webviews":["ads-window"],"permissions":["shell:allow-open","ads:default"]},"core":{"identifier":"core","description":"","local":true,"windows":["main"],"permissions":["core:default","core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","core:window:allow-create","core:window:allow-maximize","core:window:allow-toggle-maximize","core:window:allow-unmaximize","core:window:allow-minimize","core:window:allow-unminimize","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-set-decorations","core:window:allow-start-dragging","core:webview:allow-set-webview-zoom"]},"plugins":{"identifier":"plugins","description":"","local":true,"windows":["main"],"permissions":["dialog:allow-open","dialog:allow-confirm","shell:allow-open","os:allow-platform","os:allow-version","os:allow-os-type","os:allow-family","os:allow-arch","os:allow-exe-extension","os:allow-locale","os:allow-hostname","deep-link:default","window-state:default","window-state:allow-restore-state","window-state:allow-save-window-state","auth:default","import:default","jre:default","logs:default","metadata:default","mr-auth:default","profile-create:default","pack:default","process:default","profile:default","cache:default","settings:default","tags:default","utils:default","ads:default"]},"updater":{"identifier":"updater","description":"","local":true,"windows":["main"],"permissions":["updater:default"]}}
|
||||||
@@ -327,6 +327,13 @@
|
|||||||
"ads:allow-scroll-ads-window"
|
"ads:allow-scroll-ads-window"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "ads:allow-show-ads-window -> Enables the show_ads_window command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ads:allow-show-ads-window"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "ads:deny-hide-ads-window -> Denies the hide_ads_window command without any pre-configured scope.",
|
"description": "ads:deny-hide-ads-window -> Denies the hide_ads_window command without any pre-configured scope.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -348,6 +355,13 @@
|
|||||||
"ads:deny-scroll-ads-window"
|
"ads:deny-scroll-ads-window"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "ads:deny-show-ads-window -> Denies the show_ads_window command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ads:deny-show-ads-window"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "auth:default -> Default plugin permissions.",
|
"description": "auth:default -> Default plugin permissions.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -2834,10 +2848,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "jre:allow-set-java-versions -> Enables the set_java_versions command without any pre-configured scope.",
|
"description": "jre:allow-set-java-version -> Enables the set_java_version command without any pre-configured scope.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"jre:allow-set-java-versions"
|
"jre:allow-set-java-version"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2883,10 +2897,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "jre:deny-set-java-versions -> Denies the set_java_versions command without any pre-configured scope.",
|
"description": "jre:deny-set-java-version -> Denies the set_java_version command without any pre-configured scope.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"jre:deny-set-java-versions"
|
"jre:deny-set-java-version"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -3904,6 +3918,69 @@
|
|||||||
"tags:deny-tags-get-report-types"
|
"tags:deny-tags-get-report-types"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:default -> This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:default"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:allow-check -> Enables the check command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:allow-check"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:allow-download -> Enables the download command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:allow-download"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:allow-download-and-install -> Enables the download_and_install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:allow-download-and-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:allow-install -> Enables the install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:allow-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:deny-check -> Denies the check command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:deny-check"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:deny-download -> Denies the download command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:deny-download"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:deny-download-and-install -> Denies the download_and_install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:deny-download-and-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:deny-install -> Denies the install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:deny-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "utils:default -> Default plugin permissions.",
|
"description": "utils:default -> Default plugin permissions.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@@ -327,6 +327,13 @@
|
|||||||
"ads:allow-scroll-ads-window"
|
"ads:allow-scroll-ads-window"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "ads:allow-show-ads-window -> Enables the show_ads_window command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ads:allow-show-ads-window"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "ads:deny-hide-ads-window -> Denies the hide_ads_window command without any pre-configured scope.",
|
"description": "ads:deny-hide-ads-window -> Denies the hide_ads_window command without any pre-configured scope.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -348,6 +355,13 @@
|
|||||||
"ads:deny-scroll-ads-window"
|
"ads:deny-scroll-ads-window"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "ads:deny-show-ads-window -> Denies the show_ads_window command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ads:deny-show-ads-window"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "auth:default -> Default plugin permissions.",
|
"description": "auth:default -> Default plugin permissions.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -2834,10 +2848,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "jre:allow-set-java-versions -> Enables the set_java_versions command without any pre-configured scope.",
|
"description": "jre:allow-set-java-version -> Enables the set_java_version command without any pre-configured scope.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"jre:allow-set-java-versions"
|
"jre:allow-set-java-version"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2883,10 +2897,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "jre:deny-set-java-versions -> Denies the set_java_versions command without any pre-configured scope.",
|
"description": "jre:deny-set-java-version -> Denies the set_java_version command without any pre-configured scope.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"jre:deny-set-java-versions"
|
"jre:deny-set-java-version"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -3904,6 +3918,69 @@
|
|||||||
"tags:deny-tags-get-report-types"
|
"tags:deny-tags-get-report-types"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:default -> This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:default"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:allow-check -> Enables the check command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:allow-check"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:allow-download -> Enables the download command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:allow-download"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:allow-download-and-install -> Enables the download_and_install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:allow-download-and-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:allow-install -> Enables the install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:allow-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:deny-check -> Denies the check command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:deny-check"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:deny-download -> Denies the download command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:deny-download"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:deny-download-and-install -> Denies the download_and_install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:deny-download-and-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "updater:deny-install -> Denies the install command without any pre-configured scope.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"updater:deny-install"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "utils:default -> Default plugin permissions.",
|
"description": "utils:default -> Default plugin permissions.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
document.addEventListener('click', function (e) {
|
if (!window.modrinthClickListener) {
|
||||||
let target = e.target
|
window.modrinthClickListener = true
|
||||||
while (target != null) {
|
document.addEventListener('click', function (e) {
|
||||||
if (target.matches('a')) {
|
let target = e.target
|
||||||
e.preventDefault()
|
while (target != null) {
|
||||||
if (target.href) {
|
if (target.matches('a')) {
|
||||||
window.top.postMessage({ modrinthOpenUrl: target.href }, 'https://modrinth.com')
|
e.preventDefault()
|
||||||
|
if (target.href) {
|
||||||
|
window.top.postMessage({ modrinthOpenUrl: target.href }, 'https://modrinth.com')
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
break
|
target = target.parentElement
|
||||||
}
|
}
|
||||||
target = target.parentElement
|
})
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
window.open = (url, target, features) => {
|
window.open = (url, target, features) => {
|
||||||
window.top.postMessage({ modrinthOpenUrl: url }, 'https://modrinth.com')
|
window.top.postMessage({ modrinthOpenUrl: url }, 'https://modrinth.com')
|
||||||
|
|||||||
@@ -1,51 +1,105 @@
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tauri::plugin::TauriPlugin;
|
use tauri::plugin::TauriPlugin;
|
||||||
use tauri::{
|
use tauri::{Emitter, LogicalPosition, LogicalSize, Manager, Runtime};
|
||||||
Emitter, LogicalPosition, LogicalSize, Manager, Runtime, WebviewUrl,
|
use tokio::sync::RwLock;
|
||||||
};
|
|
||||||
|
pub struct AdsState {
|
||||||
|
pub shown: bool,
|
||||||
|
pub size: Option<LogicalSize<f32>>,
|
||||||
|
pub position: Option<LogicalPosition<f32>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||||
tauri::plugin::Builder::<R>::new("ads")
|
tauri::plugin::Builder::<R>::new("ads")
|
||||||
|
.setup(|app, _api| {
|
||||||
|
app.manage(RwLock::new(AdsState {
|
||||||
|
shown: true,
|
||||||
|
size: None,
|
||||||
|
position: None,
|
||||||
|
}));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
init_ads_window,
|
init_ads_window,
|
||||||
hide_ads_window,
|
hide_ads_window,
|
||||||
scroll_ads_window,
|
scroll_ads_window,
|
||||||
|
show_ads_window,
|
||||||
])
|
])
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
const LINK_SCRIPT: &str = include_str!("ads-init.js");
|
|
||||||
|
|
||||||
// TODO: make ads work on linux
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
pub async fn init_ads_window<R: Runtime>(
|
pub async fn init_ads_window<R: Runtime>(
|
||||||
app: tauri::AppHandle<R>,
|
app: tauri::AppHandle<R>,
|
||||||
x: f32,
|
x: f32,
|
||||||
y: f32,
|
y: f32,
|
||||||
width: f32,
|
width: f32,
|
||||||
height: f32,
|
height: f32,
|
||||||
|
override_shown: bool,
|
||||||
) -> crate::api::Result<()> {
|
) -> crate::api::Result<()> {
|
||||||
#[cfg(not(target_os = "linux"))]
|
use tauri::WebviewUrl;
|
||||||
{
|
const LINK_SCRIPT: &str = include_str!("ads-init.js");
|
||||||
if let Some(webview) = app.webviews().get("ads-window") {
|
|
||||||
|
let state = app.state::<RwLock<AdsState>>();
|
||||||
|
let mut state = state.write().await;
|
||||||
|
state.size = Some(LogicalSize::new(width, height));
|
||||||
|
state.position = Some(LogicalPosition::new(x, y));
|
||||||
|
|
||||||
|
if override_shown {
|
||||||
|
state.shown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(webview) = app.webviews().get("ads-window") {
|
||||||
|
if state.shown {
|
||||||
let _ = webview.set_position(LogicalPosition::new(x, y));
|
let _ = webview.set_position(LogicalPosition::new(x, y));
|
||||||
let _ = webview.set_size(LogicalSize::new(width, height));
|
let _ = webview.set_size(LogicalSize::new(width, height));
|
||||||
} else if let Some(window) = app.get_window("main") {
|
}
|
||||||
let _ = window.add_child(
|
} else if let Some(window) = app.get_window("main") {
|
||||||
tauri::webview::WebviewBuilder::new(
|
let _ = window.add_child(
|
||||||
"ads-window",
|
tauri::webview::WebviewBuilder::new(
|
||||||
WebviewUrl::External(
|
"ads-window",
|
||||||
"https://modrinth.com/wrapper/app-ads".parse().unwrap(),
|
WebviewUrl::External(
|
||||||
),
|
"https://modrinth.com/wrapper/app-ads".parse().unwrap(),
|
||||||
)
|
),
|
||||||
.initialization_script(LINK_SCRIPT)
|
)
|
||||||
.user_agent("ModrinthApp Ads Webview")
|
.initialization_script(LINK_SCRIPT)
|
||||||
.zoom_hotkeys_enabled(false)
|
.user_agent("ModrinthApp Ads Webview")
|
||||||
.transparent(true),
|
.zoom_hotkeys_enabled(false)
|
||||||
LogicalPosition::new(x, y),
|
.transparent(true),
|
||||||
LogicalSize::new(width, height),
|
if state.shown {
|
||||||
);
|
LogicalPosition::new(x, y)
|
||||||
|
} else {
|
||||||
|
LogicalPosition::new(-1000.0, -1000.0)
|
||||||
|
},
|
||||||
|
LogicalSize::new(width, height),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make ads work on linux
|
||||||
|
#[tauri::command]
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub async fn init_ads_window() {}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn show_ads_window<R: Runtime>(
|
||||||
|
app: tauri::AppHandle<R>,
|
||||||
|
) -> crate::api::Result<()> {
|
||||||
|
if let Some(webview) = app.webviews().get("ads-window") {
|
||||||
|
let state = app.state::<RwLock<AdsState>>();
|
||||||
|
let mut state = state.write().await;
|
||||||
|
|
||||||
|
state.shown = true;
|
||||||
|
if let Some(size) = state.size {
|
||||||
|
let _ = webview.set_size(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(position) = state.position {
|
||||||
|
let _ = webview.set_position(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,12 +109,19 @@ pub async fn init_ads_window<R: Runtime>(
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn hide_ads_window<R: Runtime>(
|
pub async fn hide_ads_window<R: Runtime>(
|
||||||
app: tauri::AppHandle<R>,
|
app: tauri::AppHandle<R>,
|
||||||
|
reset: Option<bool>,
|
||||||
) -> crate::api::Result<()> {
|
) -> crate::api::Result<()> {
|
||||||
#[cfg(not(target_os = "linux"))]
|
if let Some(webview) = app.webviews().get("ads-window") {
|
||||||
{
|
let state = app.state::<RwLock<AdsState>>();
|
||||||
if let Some(webview) = app.webviews().get("ads-window") {
|
let mut state = state.write().await;
|
||||||
let _ = webview.set_position(LogicalPosition::new(-1000, -1000));
|
state.shown = false;
|
||||||
|
|
||||||
|
if reset.unwrap_or(false) {
|
||||||
|
state.size = None;
|
||||||
|
state.position = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _ = webview.set_position(LogicalPosition::new(-1000, -1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ pub enum TheseusSerializableError {
|
|||||||
|
|
||||||
#[error("Tauri error: {0}")]
|
#[error("Tauri error: {0}")]
|
||||||
Tauri(#[from] tauri::Error),
|
Tauri(#[from] tauri::Error),
|
||||||
|
|
||||||
|
#[cfg(feature = "updater")]
|
||||||
|
#[error("Tauri updater error: {0}")]
|
||||||
|
TauriUpdater(#[from] tauri_plugin_updater::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic implementation of From<T> for ErrorTypeA
|
// Generic implementation of From<T> for ErrorTypeA
|
||||||
@@ -87,7 +91,15 @@ macro_rules! impl_serialize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use the macro to implement Serialize for TheseusSerializableError
|
// Use the macro to implement Serialize for TheseusSerializableError
|
||||||
|
#[cfg(not(feature = "updater"))]
|
||||||
impl_serialize! {
|
impl_serialize! {
|
||||||
IO,
|
IO,
|
||||||
Tauri,
|
Tauri,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "updater")]
|
||||||
|
impl_serialize! {
|
||||||
|
IO,
|
||||||
|
Tauri,
|
||||||
|
TauriUpdater,
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,7 +26,67 @@ extern crate objc;
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn initialize_state(app: tauri::AppHandle) -> api::Result<()> {
|
async fn initialize_state(app: tauri::AppHandle) -> api::Result<()> {
|
||||||
theseus::EventState::init(app.clone()).await?;
|
theseus::EventState::init(app.clone()).await?;
|
||||||
State::init().await?;
|
|
||||||
|
#[cfg(feature = "updater")]
|
||||||
|
{
|
||||||
|
use tauri_plugin_updater::UpdaterExt;
|
||||||
|
|
||||||
|
let updater = app.updater_builder().build()?;
|
||||||
|
|
||||||
|
let update_fut = updater.check();
|
||||||
|
|
||||||
|
State::init().await?;
|
||||||
|
|
||||||
|
let check_bar = theseus::init_loading(
|
||||||
|
theseus::LoadingBarType::CheckingForUpdates,
|
||||||
|
1.0,
|
||||||
|
"Checking for updates...",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let update = update_fut.await;
|
||||||
|
|
||||||
|
drop(check_bar);
|
||||||
|
|
||||||
|
if let Some(update) = update.ok().flatten() {
|
||||||
|
tracing::info!("Update found: {:?}", update.download_url);
|
||||||
|
let loader_bar_id = theseus::init_loading(
|
||||||
|
theseus::LoadingBarType::LauncherUpdate {
|
||||||
|
version: update.version.clone(),
|
||||||
|
current_version: update.current_version.clone(),
|
||||||
|
},
|
||||||
|
1.0,
|
||||||
|
"Updating Modrinth App...",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// 100 MiB
|
||||||
|
const DEFAULT_CONTENT_LENGTH: u64 = 1024 * 1024 * 100;
|
||||||
|
|
||||||
|
update
|
||||||
|
.download_and_install(
|
||||||
|
|chunk_length, content_length| {
|
||||||
|
let _ = theseus::emit_loading(
|
||||||
|
&loader_bar_id,
|
||||||
|
(chunk_length as f64)
|
||||||
|
/ (content_length
|
||||||
|
.unwrap_or(DEFAULT_CONTENT_LENGTH)
|
||||||
|
as f64),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|| {},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
app.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "updater"))]
|
||||||
|
{
|
||||||
|
State::init().await?;
|
||||||
|
}
|
||||||
|
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
app.asset_protocol_scope()
|
app.asset_protocol_scope()
|
||||||
@@ -75,6 +135,11 @@ async fn toggle_decorations(b: bool, window: tauri::Window) -> api::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn restart_app(app: tauri::AppHandle) {
|
||||||
|
app.restart();
|
||||||
|
}
|
||||||
|
|
||||||
// if Tauri app is called with arguments, then those arguments will be treated as commands
|
// if Tauri app is called with arguments, then those arguments will be treated as commands
|
||||||
// ie: deep links or filepaths for .mrpacks
|
// ie: deep links or filepaths for .mrpacks
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -104,6 +169,19 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
builder = builder
|
builder = builder
|
||||||
|
.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
|
||||||
|
if let Some(payload) = args.get(1) {
|
||||||
|
tracing::info!("Handling deep link from arg {payload}");
|
||||||
|
let payload = payload.clone();
|
||||||
|
tauri::async_runtime::spawn(api::utils::handle_command(
|
||||||
|
payload,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(win) = app.get_window("main") {
|
||||||
|
let _ = win.set_focus();
|
||||||
|
}
|
||||||
|
}))
|
||||||
.plugin(tauri_plugin_os::init())
|
.plugin(tauri_plugin_os::init())
|
||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_deep_link::init())
|
.plugin(tauri_plugin_deep_link::init())
|
||||||
@@ -188,6 +266,7 @@ fn main() {
|
|||||||
toggle_decorations,
|
toggle_decorations,
|
||||||
api::mr_auth::modrinth_auth_login,
|
api::mr_auth::modrinth_auth_login,
|
||||||
show_window,
|
show_window,
|
||||||
|
restart_app,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
|||||||
@@ -5,10 +5,15 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"features": ["updater"]
|
"features": ["updater"]
|
||||||
},
|
},
|
||||||
|
"app": {
|
||||||
|
"security": {
|
||||||
|
"capabilities": ["ads", "core", "plugins", "updater"]
|
||||||
|
}
|
||||||
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"updater": {
|
"updater": {
|
||||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDIwMzM5QkE0M0FCOERBMzkKUldRNTJyZzZwSnN6SUdPRGdZREtUUGxMblZqeG9OVHYxRUlRTzJBc2U3MUNJaDMvZDQ1UytZZmYK",
|
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDIwMzM5QkE0M0FCOERBMzkKUldRNTJyZzZwSnN6SUdPRGdZREtUUGxMblZqeG9OVHYxRUlRTzJBc2U3MUNJaDMvZDQ1UytZZmYK",
|
||||||
"endpoints": ["https://launcher-files.modrinth.com/updates.json"]
|
"endpoints": ["https://launcher-files.modrinth.com/updates.json"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"productName": "Modrinth App",
|
"productName": "Modrinth App",
|
||||||
"version": "0.8.4",
|
"version": "0.8.5",
|
||||||
"identifier": "ModrinthApp",
|
"identifier": "ModrinthApp",
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"deep-link": {
|
"deep-link": {
|
||||||
@@ -86,6 +86,7 @@
|
|||||||
],
|
],
|
||||||
"enable": true
|
"enable": true
|
||||||
},
|
},
|
||||||
|
"capabilities": ["ads", "core", "plugins"],
|
||||||
"csp": {
|
"csp": {
|
||||||
"default-src": "'self' customprotocol: asset:",
|
"default-src": "'self' customprotocol: asset:",
|
||||||
"connect-src": "ipc: http://ipc.localhost https://modrinth.com https://*.modrinth.com https://*.posthog.com https://*.sentry.io https://*.cloudflare.com https://api.mclo.gs https://cmp.inmobi.com",
|
"connect-src": "ipc: http://ipc.localhost https://modrinth.com https://*.modrinth.com https://*.posthog.com https://*.sentry.io https://*.cloudflare.com https://api.mclo.gs https://cmp.inmobi.com",
|
||||||
|
|||||||
@@ -78,16 +78,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById("plus-link").addEventListener("click", (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
if (event.data.modrinthOpenUrl && window.__TAURI_INTERNALS__) {
|
|
||||||
window.__TAURI_INTERNALS__.invoke("plugin:shell|open", {
|
|
||||||
path: this.href,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener("contextmenu", (event) => event.preventDefault());
|
document.addEventListener("contextmenu", (event) => event.preventDefault());
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "theseus"
|
name = "theseus"
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
|
|||||||
pub name: PathBuf,
|
pub name: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_loading(&loading_bar, 0.0, Some("Fetching java version")).await?;
|
emit_loading(&loading_bar, 0.0, Some("Fetching java version"))?;
|
||||||
let packages = fetch_json::<Vec<Package>>(
|
let packages = fetch_json::<Vec<Package>>(
|
||||||
Method::GET,
|
Method::GET,
|
||||||
&format!(
|
&format!(
|
||||||
@@ -80,7 +80,7 @@ pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
|
|||||||
&state.fetch_semaphore,
|
&state.fetch_semaphore,
|
||||||
&state.pool,
|
&state.pool,
|
||||||
).await?;
|
).await?;
|
||||||
emit_loading(&loading_bar, 10.0, Some("Downloading java version")).await?;
|
emit_loading(&loading_bar, 10.0, Some("Downloading java version"))?;
|
||||||
|
|
||||||
if let Some(download) = packages.first() {
|
if let Some(download) = packages.first() {
|
||||||
let file = fetch_advanced(
|
let file = fetch_advanced(
|
||||||
@@ -115,13 +115,13 @@ pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_loading(&loading_bar, 0.0, Some("Extracting java")).await?;
|
emit_loading(&loading_bar, 0.0, Some("Extracting java"))?;
|
||||||
archive.extract(&path).map_err(|_| {
|
archive.extract(&path).map_err(|_| {
|
||||||
crate::Error::from(crate::ErrorKind::InputError(
|
crate::Error::from(crate::ErrorKind::InputError(
|
||||||
"Failed to extract java zip".to_string(),
|
"Failed to extract java zip".to_string(),
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
emit_loading(&loading_bar, 10.0, Some("Done extracting java")).await?;
|
emit_loading(&loading_bar, 10.0, Some("Done extracting java"))?;
|
||||||
let mut base_path = path.join(
|
let mut base_path = path.join(
|
||||||
download
|
download
|
||||||
.name
|
.name
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ pub async fn copy_dotminecraft(
|
|||||||
|
|
||||||
fetch::copy(&src_child, &dst_child, io_semaphore).await?;
|
fetch::copy(&src_child, &dst_child, io_semaphore).await?;
|
||||||
|
|
||||||
emit_loading(&loading_bar, 1.0, None).await?;
|
emit_loading(&loading_bar, 1.0, None)?;
|
||||||
}
|
}
|
||||||
Ok(loading_bar)
|
Ok(loading_bar)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ pub async fn generate_pack_from_version_id(
|
|||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
|
|
||||||
let loading_bar = if let Some(bar) = initialized_loading_bar {
|
let loading_bar = if let Some(bar) = initialized_loading_bar {
|
||||||
emit_loading(&bar, 0.0, Some("Downloading pack file")).await?;
|
emit_loading(&bar, 0.0, Some("Downloading pack file"))?;
|
||||||
bar
|
bar
|
||||||
} else {
|
} else {
|
||||||
init_loading(
|
init_loading(
|
||||||
@@ -207,7 +207,7 @@ pub async fn generate_pack_from_version_id(
|
|||||||
.await?
|
.await?
|
||||||
};
|
};
|
||||||
|
|
||||||
emit_loading(&loading_bar, 0.0, Some("Fetching version")).await?;
|
emit_loading(&loading_bar, 0.0, Some("Fetching version"))?;
|
||||||
let version = CachedEntry::get_version(
|
let version = CachedEntry::get_version(
|
||||||
&version_id,
|
&version_id,
|
||||||
None,
|
None,
|
||||||
@@ -220,7 +220,7 @@ pub async fn generate_pack_from_version_id(
|
|||||||
"Invalid version ID specified!".to_string(),
|
"Invalid version ID specified!".to_string(),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
emit_loading(&loading_bar, 10.0, None).await?;
|
emit_loading(&loading_bar, 10.0, None)?;
|
||||||
|
|
||||||
let (url, hash) =
|
let (url, hash) =
|
||||||
if let Some(file) = version.files.iter().find(|x| x.primary) {
|
if let Some(file) = version.files.iter().find(|x| x.primary) {
|
||||||
@@ -248,7 +248,7 @@ pub async fn generate_pack_from_version_id(
|
|||||||
&state.pool,
|
&state.pool,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
emit_loading(&loading_bar, 0.0, Some("Fetching project metadata")).await?;
|
emit_loading(&loading_bar, 0.0, Some("Fetching project metadata"))?;
|
||||||
|
|
||||||
let project = CachedEntry::get_project(
|
let project = CachedEntry::get_project(
|
||||||
&version.project_id,
|
&version.project_id,
|
||||||
@@ -263,7 +263,7 @@ pub async fn generate_pack_from_version_id(
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
emit_loading(&loading_bar, 10.0, Some("Retrieving icon")).await?;
|
emit_loading(&loading_bar, 10.0, Some("Retrieving icon"))?;
|
||||||
let icon = if let Some(icon_url) = project.icon_url {
|
let icon = if let Some(icon_url) = project.icon_url {
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let icon_bytes =
|
let icon_bytes =
|
||||||
@@ -287,7 +287,7 @@ pub async fn generate_pack_from_version_id(
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
emit_loading(&loading_bar, 10.0, None).await?;
|
emit_loading(&loading_bar, 10.0, None)?;
|
||||||
|
|
||||||
Ok(CreatePack {
|
Ok(CreatePack {
|
||||||
file,
|
file,
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ pub async fn install_zipped_mrpack_files(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
emit_loading(&loading_bar, 0.0, Some("Extracting overrides")).await?;
|
emit_loading(&loading_bar, 0.0, Some("Extracting overrides"))?;
|
||||||
|
|
||||||
let mut total_len = 0;
|
let mut total_len = 0;
|
||||||
|
|
||||||
@@ -270,8 +270,7 @@ pub async fn install_zipped_mrpack_files(
|
|||||||
"Extracting override {}/{}",
|
"Extracting override {}/{}",
|
||||||
index, total_len
|
index, total_len
|
||||||
)),
|
)),
|
||||||
)
|
)?;
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -510,7 +510,7 @@ pub async fn export_mrpack(
|
|||||||
// Iterate over every file in the folder
|
// Iterate over every file in the folder
|
||||||
// Every file that is NOT in the config file is added to the zip, in overrides
|
// Every file that is NOT in the config file is added to the zip, in overrides
|
||||||
for path in path_list {
|
for path in path_list {
|
||||||
emit_loading(&loading_bar, 1.0, None).await?;
|
emit_loading(&loading_bar, 1.0, None)?;
|
||||||
|
|
||||||
let relative_path = pack_get_relative_path(&profile_base_path, &path)?;
|
let relative_path = pack_get_relative_path(&profile_base_path, &path)?;
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const CLI_PROGRESS_BAR_TOTAL: u64 = 1000;
|
|||||||
pub async fn loading_function() -> crate::Result<()> {
|
pub async fn loading_function() -> crate::Result<()> {
|
||||||
let loading_bar = init_loading(LoadingBarType::StateInit, 100.0, "Loading something long...").await;
|
let loading_bar = init_loading(LoadingBarType::StateInit, 100.0, "Loading something long...").await;
|
||||||
for i in 0..100 {
|
for i in 0..100 {
|
||||||
emit_loading(&loading_bar, 1.0, None).await?;
|
emit_loading(&loading_bar, 1.0, None)?;
|
||||||
tokio::time::sleep(Duration::from_millis(100)).await;
|
tokio::time::sleep(Duration::from_millis(100)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ pub async fn init_loading_unsafe(
|
|||||||
total: f64,
|
total: f64,
|
||||||
title: &str,
|
title: &str,
|
||||||
) -> crate::Result<LoadingBarId> {
|
) -> crate::Result<LoadingBarId> {
|
||||||
let event_state = crate::EventState::get().await?;
|
let event_state = crate::EventState::get()?;
|
||||||
let key = LoadingBarId(Uuid::new_v4());
|
let key = LoadingBarId(Uuid::new_v4());
|
||||||
|
|
||||||
event_state.loading_bars.insert(
|
event_state.loading_bars.insert(
|
||||||
@@ -91,7 +91,7 @@ pub async fn init_loading_unsafe(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
// attempt an initial loading_emit event to the frontend
|
// attempt an initial loading_emit event to the frontend
|
||||||
emit_loading(&key, 0.0, None).await?;
|
emit_loading(&key, 0.0, None)?;
|
||||||
Ok(key)
|
Ok(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ pub async fn edit_loading(
|
|||||||
total: f64,
|
total: f64,
|
||||||
title: &str,
|
title: &str,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let event_state = crate::EventState::get().await?;
|
let event_state = crate::EventState::get()?;
|
||||||
|
|
||||||
if let Some(mut bar) = event_state.loading_bars.get_mut(&id.0) {
|
if let Some(mut bar) = event_state.loading_bars.get_mut(&id.0) {
|
||||||
bar.bar_type = bar_type;
|
bar.bar_type = bar_type;
|
||||||
@@ -132,7 +132,7 @@ pub async fn edit_loading(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
emit_loading(id, 0.0, None).await?;
|
emit_loading(id, 0.0, None)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,12 +144,12 @@ pub async fn edit_loading(
|
|||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
#[tracing::instrument(level = "debug")]
|
#[tracing::instrument(level = "debug")]
|
||||||
|
|
||||||
pub async fn emit_loading(
|
pub fn emit_loading(
|
||||||
key: &LoadingBarId,
|
key: &LoadingBarId,
|
||||||
increment_frac: f64,
|
increment_frac: f64,
|
||||||
message: Option<&str>,
|
message: Option<&str>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
let event_state = crate::EventState::get().await?;
|
let event_state = crate::EventState::get()?;
|
||||||
|
|
||||||
let mut loading_bar = match event_state.loading_bars.get_mut(&key.0) {
|
let mut loading_bar = match event_state.loading_bars.get_mut(&key.0) {
|
||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
@@ -211,7 +211,7 @@ pub async fn emit_loading(
|
|||||||
pub async fn emit_warning(message: &str) -> crate::Result<()> {
|
pub async fn emit_warning(message: &str) -> crate::Result<()> {
|
||||||
#[cfg(feature = "tauri")]
|
#[cfg(feature = "tauri")]
|
||||||
{
|
{
|
||||||
let event_state = crate::EventState::get().await?;
|
let event_state = crate::EventState::get()?;
|
||||||
event_state
|
event_state
|
||||||
.app
|
.app
|
||||||
.emit(
|
.emit(
|
||||||
@@ -235,7 +235,7 @@ pub async fn emit_command(command: CommandPayload) -> crate::Result<()> {
|
|||||||
tracing::debug!("Command: {}", serde_json::to_string(&command)?);
|
tracing::debug!("Command: {}", serde_json::to_string(&command)?);
|
||||||
#[cfg(feature = "tauri")]
|
#[cfg(feature = "tauri")]
|
||||||
{
|
{
|
||||||
let event_state = crate::EventState::get().await?;
|
let event_state = crate::EventState::get()?;
|
||||||
event_state
|
event_state
|
||||||
.app
|
.app
|
||||||
.emit("command", command)
|
.emit("command", command)
|
||||||
@@ -254,7 +254,7 @@ pub async fn emit_process(
|
|||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
#[cfg(feature = "tauri")]
|
#[cfg(feature = "tauri")]
|
||||||
{
|
{
|
||||||
let event_state = crate::EventState::get().await?;
|
let event_state = crate::EventState::get()?;
|
||||||
event_state
|
event_state
|
||||||
.app
|
.app
|
||||||
.emit(
|
.emit(
|
||||||
@@ -279,7 +279,7 @@ pub async fn emit_profile(
|
|||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
#[cfg(feature = "tauri")]
|
#[cfg(feature = "tauri")]
|
||||||
{
|
{
|
||||||
let event_state = crate::EventState::get().await?;
|
let event_state = crate::EventState::get()?;
|
||||||
event_state
|
event_state
|
||||||
.app
|
.app
|
||||||
.emit(
|
.emit(
|
||||||
@@ -329,7 +329,7 @@ macro_rules! loading_join {
|
|||||||
async move {
|
async move {
|
||||||
let res = $task.await;
|
let res = $task.await;
|
||||||
if let Some(key) = key {
|
if let Some(key) = key {
|
||||||
$crate::event::emit::emit_loading(key, increment, message).await?;
|
$crate::event::emit::emit_loading(key, increment, message)?;
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
@@ -376,8 +376,7 @@ where
|
|||||||
async move {
|
async move {
|
||||||
f.await?;
|
f.await?;
|
||||||
if let Some(key) = key {
|
if let Some(key) = key {
|
||||||
emit_loading(key, total / (num_futs as f64), message)
|
emit_loading(key, total / (num_futs as f64), message)?;
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,21 +45,14 @@ impl EventState {
|
|||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tauri")]
|
pub fn get() -> crate::Result<Arc<Self>> {
|
||||||
pub async fn get() -> crate::Result<Arc<Self>> {
|
|
||||||
Ok(EVENT_STATE.get().ok_or(EventError::NotInitialized)?.clone())
|
Ok(EVENT_STATE.get().ok_or(EventError::NotInitialized)?.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialization requires no app handle in non-tauri mode, so we can just use the same function
|
|
||||||
#[cfg(not(feature = "tauri"))]
|
|
||||||
pub async fn get() -> crate::Result<Arc<Self>> {
|
|
||||||
Self::init().await
|
|
||||||
}
|
|
||||||
|
|
||||||
// Values provided should not be used directly, as they are clones and are not guaranteed to be up-to-date
|
// Values provided should not be used directly, as they are clones and are not guaranteed to be up-to-date
|
||||||
pub async fn list_progress_bars() -> crate::Result<DashMap<Uuid, LoadingBar>>
|
pub async fn list_progress_bars() -> crate::Result<DashMap<Uuid, LoadingBar>>
|
||||||
{
|
{
|
||||||
let value = Self::get().await?;
|
let value = Self::get()?;
|
||||||
Ok(value.loading_bars.clone())
|
Ok(value.loading_bars.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +60,7 @@ impl EventState {
|
|||||||
pub async fn get_main_window() -> crate::Result<Option<tauri::WebviewWindow>>
|
pub async fn get_main_window() -> crate::Result<Option<tauri::WebviewWindow>>
|
||||||
{
|
{
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
let value = Self::get().await?;
|
let value = Self::get()?;
|
||||||
Ok(value.app.get_webview_window("main"))
|
Ok(value.app.get_webview_window("main"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +88,7 @@ impl Drop for LoadingBarId {
|
|||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let loader_uuid = self.0;
|
let loader_uuid = self.0;
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Ok(event_state) = EventState::get().await {
|
if let Ok(event_state) = EventState::get() {
|
||||||
#[cfg(any(feature = "tauri", feature = "cli"))]
|
#[cfg(any(feature = "tauri", feature = "cli"))]
|
||||||
if let Some((_, bar)) =
|
if let Some((_, bar)) =
|
||||||
event_state.loading_bars.remove(&loader_uuid)
|
event_state.loading_bars.remove(&loader_uuid)
|
||||||
@@ -180,6 +173,11 @@ pub enum LoadingBarType {
|
|||||||
import_location: PathBuf,
|
import_location: PathBuf,
|
||||||
profile_name: String,
|
profile_name: String,
|
||||||
},
|
},
|
||||||
|
CheckingForUpdates,
|
||||||
|
LauncherUpdate {
|
||||||
|
version: String,
|
||||||
|
current_version: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Clone)]
|
#[derive(Serialize, Clone)]
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ pub async fn download_version_info(
|
|||||||
}?;
|
}?;
|
||||||
|
|
||||||
if let Some(loading_bar) = loading_bar {
|
if let Some(loading_bar) = loading_bar {
|
||||||
emit_loading(loading_bar, 5.0, None).await?;
|
emit_loading(loading_bar, 5.0, None)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::debug!("Loaded version info for Minecraft {version_id}");
|
tracing::debug!("Loaded version info for Minecraft {version_id}");
|
||||||
@@ -154,7 +154,7 @@ pub async fn download_client(
|
|||||||
tracing::trace!("Fetched client version {version}");
|
tracing::trace!("Fetched client version {version}");
|
||||||
}
|
}
|
||||||
if let Some(loading_bar) = loading_bar {
|
if let Some(loading_bar) = loading_bar {
|
||||||
emit_loading(loading_bar, 9.0, None).await?;
|
emit_loading(loading_bar, 9.0, None)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::debug!("Client loaded for version {version}!");
|
tracing::debug!("Client loaded for version {version}!");
|
||||||
@@ -196,7 +196,7 @@ pub async fn download_assets_index(
|
|||||||
}?;
|
}?;
|
||||||
|
|
||||||
if let Some(loading_bar) = loading_bar {
|
if let Some(loading_bar) = loading_bar {
|
||||||
emit_loading(loading_bar, 5.0, None).await?;
|
emit_loading(loading_bar, 5.0, None)?;
|
||||||
}
|
}
|
||||||
tracing::debug!("Assets index successfully loaded!");
|
tracing::debug!("Assets index successfully loaded!");
|
||||||
Ok(res)
|
Ok(res)
|
||||||
|
|||||||
@@ -336,8 +336,7 @@ pub async fn install_minecraft(
|
|||||||
server => "";
|
server => "";
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_loading(&loading_bar, 0.0, Some("Running forge processors"))
|
emit_loading(&loading_bar, 0.0, Some("Running forge processors"))?;
|
||||||
.await?;
|
|
||||||
let total_length = processors.len();
|
let total_length = processors.len();
|
||||||
|
|
||||||
// Forge processors (90-100)
|
// Forge processors (90-100)
|
||||||
@@ -402,8 +401,7 @@ pub async fn install_minecraft(
|
|||||||
"Running forge processor {}/{}",
|
"Running forge processor {}/{}",
|
||||||
index, total_length
|
index, total_length
|
||||||
)),
|
)),
|
||||||
)
|
)?;
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -414,7 +412,7 @@ pub async fn install_minecraft(
|
|||||||
async { Ok(()) }
|
async { Ok(()) }
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
emit_loading(&loading_bar, 1.0, Some("Finished installing")).await?;
|
emit_loading(&loading_bar, 1.0, Some("Finished installing"))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ mod state;
|
|||||||
|
|
||||||
pub use api::*;
|
pub use api::*;
|
||||||
pub use error::*;
|
pub use error::*;
|
||||||
pub use event::{EventState, LoadingBar, LoadingBarType};
|
pub use event::{
|
||||||
|
emit::emit_loading, emit::init_loading, EventState, LoadingBar,
|
||||||
|
LoadingBarType,
|
||||||
|
};
|
||||||
pub use logger::start_logger;
|
pub use logger::start_logger;
|
||||||
pub use state::State;
|
pub use state::State;
|
||||||
|
|||||||
@@ -330,8 +330,7 @@ impl DirectoryInfo {
|
|||||||
&loader_bar_id,
|
&loader_bar_id,
|
||||||
10.0 / (MOVE_DIRS.len() as f64),
|
10.0 / (MOVE_DIRS.len() as f64),
|
||||||
None,
|
None,
|
||||||
)
|
)?;
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let paths_len = paths.len();
|
let paths_len = paths.len();
|
||||||
@@ -380,8 +379,7 @@ impl DirectoryInfo {
|
|||||||
&loader_bar_id,
|
&loader_bar_id,
|
||||||
90.0 / paths_len as f64,
|
90.0 / paths_len as f64,
|
||||||
None,
|
None,
|
||||||
)
|
);
|
||||||
.await;
|
|
||||||
|
|
||||||
success_idxs.insert(idx);
|
success_idxs.insert(idx);
|
||||||
|
|
||||||
@@ -433,8 +431,7 @@ impl DirectoryInfo {
|
|||||||
&loader_bar_id,
|
&loader_bar_id,
|
||||||
((x.size as f64) / (total_size as f64)) * 60.0,
|
((x.size as f64) / (total_size as f64)) * 60.0,
|
||||||
None,
|
None,
|
||||||
)
|
);
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok::<(), crate::Error>(())
|
Ok::<(), crate::Error>(())
|
||||||
}
|
}
|
||||||
@@ -453,8 +450,7 @@ impl DirectoryInfo {
|
|||||||
&loader_bar_id,
|
&loader_bar_id,
|
||||||
30.0 / paths_len as f64,
|
30.0 / paths_len as f64,
|
||||||
None,
|
None,
|
||||||
)
|
)?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok::<(), crate::Error>(())
|
Ok::<(), crate::Error>(())
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ pub(crate) async fn watch_profile(
|
|||||||
{
|
{
|
||||||
let path = profile_path.join(folder);
|
let path = profile_path.join(folder);
|
||||||
|
|
||||||
if !path.exists() {
|
if !path.exists() && !path.is_symlink() {
|
||||||
crate::util::io::create_dir_all(&path).await?;
|
crate::util::io::create_dir_all(&path).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,8 +130,7 @@ pub async fn fetch_advanced(
|
|||||||
(chunk.len() as f64 / total_size as f64)
|
(chunk.len() as f64 / total_size as f64)
|
||||||
* total,
|
* total,
|
||||||
None,
|
None,
|
||||||
)
|
)?;
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(bytes::Bytes::from(bytes))
|
Ok(bytes::Bytes::from(bytes))
|
||||||
|
|||||||
@@ -886,7 +886,7 @@ a,
|
|||||||
|
|
||||||
a {
|
a {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--color-link);
|
color: var(--color-blue);
|
||||||
|
|
||||||
&:focus-visible,
|
&:focus-visible,
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|||||||
@@ -797,7 +797,7 @@ function openVideoModal() {
|
|||||||
|
|
||||||
.markdown-resource-link {
|
.markdown-resource-link {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--color-link);
|
color: var(--color-blue);
|
||||||
|
|
||||||
&:focus-visible,
|
&:focus-visible,
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<NewModal ref="modal" :noblur="noblur" danger>
|
<NewModal ref="modal" :noblur="noblur" danger :on-hide="onHide">
|
||||||
<template #title>
|
<template #title>
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
<span class="font-extrabold text-contrast text-lg">{{ title }}</span>
|
<span class="font-extrabold text-contrast text-lg">{{ title }}</span>
|
||||||
@@ -76,6 +76,12 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
onHide: {
|
||||||
|
type: Function,
|
||||||
|
default() {
|
||||||
|
return () => {}
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['proceed'])
|
const emit = defineEmits(['proceed'])
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ const props = withDefaults(
|
|||||||
closeOnEsc?: boolean
|
closeOnEsc?: boolean
|
||||||
warnOnClose?: boolean
|
warnOnClose?: boolean
|
||||||
header?: string
|
header?: string
|
||||||
|
onHide?: () => void
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
type: true,
|
type: true,
|
||||||
@@ -65,6 +66,7 @@ const props = withDefaults(
|
|||||||
danger: false,
|
danger: false,
|
||||||
closeOnEsc: true,
|
closeOnEsc: true,
|
||||||
warnOnClose: false,
|
warnOnClose: false,
|
||||||
|
onHide: () => {},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -87,6 +89,7 @@ function show(event?: MouseEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
|
props.onHide()
|
||||||
visible.value = false
|
visible.value = false
|
||||||
window.removeEventListener('mousedown', updateMousePosition)
|
window.removeEventListener('mousedown', updateMousePosition)
|
||||||
window.removeEventListener('keydown', handleKeyDown)
|
window.removeEventListener('keydown', handleKeyDown)
|
||||||
|
|||||||
@@ -34,6 +34,16 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
noblur: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
onHide: {
|
||||||
|
type: Function,
|
||||||
|
default() {
|
||||||
|
return () => {}
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const shareModal = ref(null)
|
const shareModal = ref(null)
|
||||||
@@ -115,7 +125,7 @@ defineExpose({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Modal ref="shareModal" :header="header">
|
<Modal ref="shareModal" :header="header" :noblur="noblur" :on-hide="onHide">
|
||||||
<div class="share-body">
|
<div class="share-body">
|
||||||
<div v-if="link" class="qr-wrapper">
|
<div v-if="link" class="qr-wrapper">
|
||||||
<div ref="qrCode">
|
<div ref="qrCode">
|
||||||
|
|||||||
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
@@ -62,6 +62,9 @@ importers:
|
|||||||
'@tauri-apps/plugin-shell':
|
'@tauri-apps/plugin-shell':
|
||||||
specifier: ^2.0.0-rc.0
|
specifier: ^2.0.0-rc.0
|
||||||
version: 2.0.0-rc.0
|
version: 2.0.0-rc.0
|
||||||
|
'@tauri-apps/plugin-updater':
|
||||||
|
specifier: ^2.0.0-rc.0
|
||||||
|
version: 2.0.0-rc.1
|
||||||
'@tauri-apps/plugin-window-state':
|
'@tauri-apps/plugin-window-state':
|
||||||
specifier: ^2.0.0-rc.0
|
specifier: ^2.0.0-rc.0
|
||||||
version: 2.0.0-rc.0
|
version: 2.0.0-rc.0
|
||||||
@@ -1948,6 +1951,9 @@ packages:
|
|||||||
'@tauri-apps/api@2.0.0-rc.3':
|
'@tauri-apps/api@2.0.0-rc.3':
|
||||||
resolution: {integrity: sha512-k1erUfnoOFJwL5VNFZz0BQZ2agNstG7CNOjwpdWMl1vOaVuSn4DhJtXB0Deh9lZaaDlfrykKOyZs9c3XXpMi5Q==}
|
resolution: {integrity: sha512-k1erUfnoOFJwL5VNFZz0BQZ2agNstG7CNOjwpdWMl1vOaVuSn4DhJtXB0Deh9lZaaDlfrykKOyZs9c3XXpMi5Q==}
|
||||||
|
|
||||||
|
'@tauri-apps/api@2.0.0-rc.4':
|
||||||
|
resolution: {integrity: sha512-UNiIhhKG08j4ooss2oEEVexffmWkgkYlC2M3GcX3VPtNsqFgVNL8Mcw/4Y7rO9M9S+ffAMnLOF5ypzyuyb8tyg==}
|
||||||
|
|
||||||
'@tauri-apps/cli-darwin-arm64@2.0.0-rc.4':
|
'@tauri-apps/cli-darwin-arm64@2.0.0-rc.4':
|
||||||
resolution: {integrity: sha512-CSkGon9QAGymYhDng3GTiBuyrWAkqdGimL+3hzfAA4c0yMV87Y68IZ7mwzzbmRjweImvrhuNgw4ME94d1wnGPQ==}
|
resolution: {integrity: sha512-CSkGon9QAGymYhDng3GTiBuyrWAkqdGimL+3hzfAA4c0yMV87Y68IZ7mwzzbmRjweImvrhuNgw4ME94d1wnGPQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
@@ -2087,6 +2093,9 @@ packages:
|
|||||||
'@tauri-apps/plugin-shell@2.0.0-rc.0':
|
'@tauri-apps/plugin-shell@2.0.0-rc.0':
|
||||||
resolution: {integrity: sha512-bhUcQcrqZoK8H1DFXapr5r1Z75oh6Kd5Tltz97XpZFLREEqp+KhN2Fvyh8r/fKAyenYsTYUIsDsyGdjdueuF9g==}
|
resolution: {integrity: sha512-bhUcQcrqZoK8H1DFXapr5r1Z75oh6Kd5Tltz97XpZFLREEqp+KhN2Fvyh8r/fKAyenYsTYUIsDsyGdjdueuF9g==}
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-updater@2.0.0-rc.1':
|
||||||
|
resolution: {integrity: sha512-SwQhDad/jnGIUe4eFfVBZ+0wRZthPSLwrFAl/K0Fyuu7dD/uGHS/jbATxZzwFDGfcpWOGLOsS8+LqSmY5zufHw==}
|
||||||
|
|
||||||
'@tauri-apps/plugin-window-state@2.0.0-rc.0':
|
'@tauri-apps/plugin-window-state@2.0.0-rc.0':
|
||||||
resolution: {integrity: sha512-lR8reD+D1yIHT+53v56WltLS0+Y2zIkKqTuwrvz1yNbY5Hk4Z6foFV2Byo4kJAAvi5vbeGtvxYAjSiczZK5euw==}
|
resolution: {integrity: sha512-lR8reD+D1yIHT+53v56WltLS0+Y2zIkKqTuwrvz1yNbY5Hk4Z6foFV2Byo4kJAAvi5vbeGtvxYAjSiczZK5euw==}
|
||||||
|
|
||||||
@@ -7783,6 +7792,8 @@ snapshots:
|
|||||||
|
|
||||||
'@tauri-apps/api@2.0.0-rc.3': {}
|
'@tauri-apps/api@2.0.0-rc.3': {}
|
||||||
|
|
||||||
|
'@tauri-apps/api@2.0.0-rc.4': {}
|
||||||
|
|
||||||
'@tauri-apps/cli-darwin-arm64@2.0.0-rc.4':
|
'@tauri-apps/cli-darwin-arm64@2.0.0-rc.4':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -7881,6 +7892,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.0.0-rc.3
|
'@tauri-apps/api': 2.0.0-rc.3
|
||||||
|
|
||||||
|
'@tauri-apps/plugin-updater@2.0.0-rc.1':
|
||||||
|
dependencies:
|
||||||
|
'@tauri-apps/api': 2.0.0-rc.4
|
||||||
|
|
||||||
'@tauri-apps/plugin-window-state@2.0.0-rc.0':
|
'@tauri-apps/plugin-window-state@2.0.0-rc.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tauri-apps/api': 2.0.0-rc.3
|
'@tauri-apps/api': 2.0.0-rc.3
|
||||||
|
|||||||
Reference in New Issue
Block a user