App fixes 0.9.0 (#3034)
* push fixes to test on windows * Fix searching mods * Fix search not saving, fix scrolling issues, etc
This commit is contained in:
parent
7e8ceadfd4
commit
6ceed4b226
124
Cargo.lock
generated
124
Cargo.lock
generated
@ -8453,9 +8453,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tao"
|
name = "tao"
|
||||||
version = "0.30.8"
|
version = "0.31.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6682a07cf5bab0b8a2bd20d0a542917ab928b5edb75ebd4eda6b05cbaab872da"
|
checksum = "cc6b53216f32e60efc27dfa111268481e4dfba53e553e4cdebcaed9db36c11bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"cocoa 0.26.0",
|
"cocoa 0.26.0",
|
||||||
@ -8468,7 +8468,6 @@ dependencies = [
|
|||||||
"gdkwayland-sys",
|
"gdkwayland-sys",
|
||||||
"gdkx11-sys",
|
"gdkx11-sys",
|
||||||
"gtk",
|
"gtk",
|
||||||
"instant",
|
|
||||||
"jni",
|
"jni",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
@ -8527,8 +8526,7 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri"
|
name = "tauri"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/modrinth/tauri?rev=9c36dd3#9c36dd30ad6d19832a5dbd7ac9af0a152bb9323a"
|
||||||
checksum = "e545de0a2dfe296fa67db208266cd397c5a55ae782da77973ef4c4fac90e9f2c"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes 1.7.2",
|
"bytes 1.7.2",
|
||||||
@ -8559,11 +8557,11 @@ dependencies = [
|
|||||||
"serde_repr",
|
"serde_repr",
|
||||||
"serialize-to-javascript",
|
"serialize-to-javascript",
|
||||||
"swift-rs",
|
"swift-rs",
|
||||||
"tauri-build",
|
"tauri-build 2.0.3 (git+https://github.com/modrinth/tauri?rev=9c36dd3)",
|
||||||
"tauri-macros",
|
"tauri-macros",
|
||||||
"tauri-runtime",
|
"tauri-runtime",
|
||||||
"tauri-runtime-wry",
|
"tauri-runtime-wry",
|
||||||
"tauri-utils",
|
"tauri-utils 2.1.0 (git+https://github.com/modrinth/tauri?rev=9c36dd3)",
|
||||||
"thiserror 2.0.7",
|
"thiserror 2.0.7",
|
||||||
"tokio 1.42.0",
|
"tokio 1.42.0",
|
||||||
"tray-icon",
|
"tray-icon",
|
||||||
@ -8592,8 +8590,29 @@ dependencies = [
|
|||||||
"semver 1.0.23",
|
"semver 1.0.23",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri-codegen",
|
"tauri-codegen 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tauri-utils",
|
"tauri-utils 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tauri-winres",
|
||||||
|
"toml 0.8.19",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-build"
|
||||||
|
version = "2.0.3"
|
||||||
|
source = "git+https://github.com/modrinth/tauri?rev=9c36dd3#9c36dd30ad6d19832a5dbd7ac9af0a152bb9323a"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"cargo_toml",
|
||||||
|
"dirs 5.0.1",
|
||||||
|
"glob",
|
||||||
|
"heck 0.5.0",
|
||||||
|
"json-patch",
|
||||||
|
"schemars",
|
||||||
|
"semver 1.0.23",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tauri-utils 2.1.0 (git+https://github.com/modrinth/tauri?rev=9c36dd3)",
|
||||||
"tauri-winres",
|
"tauri-winres",
|
||||||
"toml 0.8.19",
|
"toml 0.8.19",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
@ -8604,6 +8623,31 @@ name = "tauri-codegen"
|
|||||||
version = "2.0.3"
|
version = "2.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf79faeecf301d3e969b1fae977039edb77a4c1f25cc0a961be298b54bff97cf"
|
checksum = "bf79faeecf301d3e969b1fae977039edb77a4c1f25cc0a961be298b54bff97cf"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"ico",
|
||||||
|
"json-patch",
|
||||||
|
"plist",
|
||||||
|
"png",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"semver 1.0.23",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2 0.10.8",
|
||||||
|
"syn 2.0.90",
|
||||||
|
"tauri-utils 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"thiserror 2.0.7",
|
||||||
|
"time",
|
||||||
|
"url",
|
||||||
|
"uuid 1.10.0",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-codegen"
|
||||||
|
version = "2.0.3"
|
||||||
|
source = "git+https://github.com/modrinth/tauri?rev=9c36dd3#9c36dd30ad6d19832a5dbd7ac9af0a152bb9323a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"brotli 7.0.0",
|
"brotli 7.0.0",
|
||||||
@ -8618,7 +8662,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2 0.10.8",
|
"sha2 0.10.8",
|
||||||
"syn 2.0.90",
|
"syn 2.0.90",
|
||||||
"tauri-utils",
|
"tauri-utils 2.1.0 (git+https://github.com/modrinth/tauri?rev=9c36dd3)",
|
||||||
"thiserror 2.0.7",
|
"thiserror 2.0.7",
|
||||||
"time",
|
"time",
|
||||||
"url",
|
"url",
|
||||||
@ -8629,15 +8673,14 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-macros"
|
name = "tauri-macros"
|
||||||
version = "2.0.3"
|
version = "2.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/modrinth/tauri?rev=9c36dd3#9c36dd30ad6d19832a5dbd7ac9af0a152bb9323a"
|
||||||
checksum = "c52027c8c5afb83166dacddc092ee8fff50772f9646d461d8c33ee887e447a03"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.90",
|
"syn 2.0.90",
|
||||||
"tauri-codegen",
|
"tauri-codegen 2.0.3 (git+https://github.com/modrinth/tauri?rev=9c36dd3)",
|
||||||
"tauri-utils",
|
"tauri-utils 2.1.0 (git+https://github.com/modrinth/tauri?rev=9c36dd3)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -8652,7 +8695,7 @@ dependencies = [
|
|||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri-utils",
|
"tauri-utils 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.8.19",
|
"toml 0.8.19",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
@ -8669,7 +8712,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-plugin",
|
"tauri-plugin",
|
||||||
"tauri-utils",
|
"tauri-utils 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"thiserror 2.0.7",
|
"thiserror 2.0.7",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
@ -8711,7 +8754,7 @@ dependencies = [
|
|||||||
"serde_repr",
|
"serde_repr",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-plugin",
|
"tauri-plugin",
|
||||||
"tauri-utils",
|
"tauri-utils 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"thiserror 2.0.7",
|
"thiserror 2.0.7",
|
||||||
"toml 0.8.19",
|
"toml 0.8.19",
|
||||||
"url",
|
"url",
|
||||||
@ -8821,8 +8864,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-runtime"
|
name = "tauri-runtime"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/modrinth/tauri?rev=9c36dd3#9c36dd30ad6d19832a5dbd7ac9af0a152bb9323a"
|
||||||
checksum = "cce18d43f80d4aba3aa8a0c953bbe835f3d0f2370aca75e8dbb14bd4bab27958"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dpi",
|
"dpi",
|
||||||
"gtk",
|
"gtk",
|
||||||
@ -8831,7 +8873,7 @@ dependencies = [
|
|||||||
"raw-window-handle 0.6.2",
|
"raw-window-handle 0.6.2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri-utils",
|
"tauri-utils 2.1.0 (git+https://github.com/modrinth/tauri?rev=9c36dd3)",
|
||||||
"thiserror 2.0.7",
|
"thiserror 2.0.7",
|
||||||
"url",
|
"url",
|
||||||
"windows 0.58.0",
|
"windows 0.58.0",
|
||||||
@ -8840,8 +8882,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-runtime-wry"
|
name = "tauri-runtime-wry"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/modrinth/tauri?rev=9c36dd3#9c36dd30ad6d19832a5dbd7ac9af0a152bb9323a"
|
||||||
checksum = "9f442a38863e10129ffe2cec7bd09c2dcf8a098a3a27801a476a304d5bb991d2"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gtk",
|
"gtk",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
@ -8855,7 +8896,7 @@ dependencies = [
|
|||||||
"softbuffer",
|
"softbuffer",
|
||||||
"tao",
|
"tao",
|
||||||
"tauri-runtime",
|
"tauri-runtime",
|
||||||
"tauri-utils",
|
"tauri-utils 2.1.0 (git+https://github.com/modrinth/tauri?rev=9c36dd3)",
|
||||||
"url",
|
"url",
|
||||||
"webkit2gtk",
|
"webkit2gtk",
|
||||||
"webview2-com",
|
"webview2-com",
|
||||||
@ -8868,6 +8909,41 @@ name = "tauri-utils"
|
|||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9271a88f99b4adea0dc71d0baca4505475a0bbd139fb135f62958721aaa8fe54"
|
checksum = "9271a88f99b4adea0dc71d0baca4505475a0bbd139fb135f62958721aaa8fe54"
|
||||||
|
dependencies = [
|
||||||
|
"cargo_metadata",
|
||||||
|
"ctor",
|
||||||
|
"dunce",
|
||||||
|
"glob",
|
||||||
|
"html5ever",
|
||||||
|
"http 1.1.0",
|
||||||
|
"infer 0.16.0",
|
||||||
|
"json-patch",
|
||||||
|
"kuchikiki",
|
||||||
|
"log",
|
||||||
|
"memchr",
|
||||||
|
"phf 0.11.2",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"schemars",
|
||||||
|
"semver 1.0.23",
|
||||||
|
"serde",
|
||||||
|
"serde-untagged",
|
||||||
|
"serde_json",
|
||||||
|
"serde_with",
|
||||||
|
"swift-rs",
|
||||||
|
"thiserror 2.0.7",
|
||||||
|
"toml 0.8.19",
|
||||||
|
"url",
|
||||||
|
"urlpattern",
|
||||||
|
"uuid 1.10.0",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-utils"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "git+https://github.com/modrinth/tauri?rev=9c36dd3#9c36dd30ad6d19832a5dbd7ac9af0a152bb9323a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli 7.0.0",
|
"brotli 7.0.0",
|
||||||
"cargo_metadata",
|
"cargo_metadata",
|
||||||
@ -9026,7 +9102,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tauri-plugin-deep-link",
|
"tauri-plugin-deep-link",
|
||||||
"tauri-plugin-dialog",
|
"tauri-plugin-dialog",
|
||||||
"tauri-plugin-opener",
|
"tauri-plugin-opener",
|
||||||
|
|||||||
@ -19,3 +19,6 @@ strip = true # Remove debug symbols
|
|||||||
|
|
||||||
[profile.dev.package.sqlx-macros]
|
[profile.dev.package.sqlx-macros]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
tauri = { git = "https://github.com/modrinth/tauri", rev = "9c36dd3" }
|
||||||
@ -127,7 +127,6 @@ 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...'
|
||||||
|
|||||||
@ -49,17 +49,3 @@ export const releaseColor = (releaseType) => {
|
|||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function debounce(fn, wait) {
|
|
||||||
let timer
|
|
||||||
return function (...args) {
|
|
||||||
if (timer) {
|
|
||||||
clearTimeout(timer) // clear any pre-existing timer
|
|
||||||
}
|
|
||||||
|
|
||||||
const context = this // get the current context
|
|
||||||
timer = setTimeout(() => {
|
|
||||||
fn.apply(context, args) // call the function if time expires
|
|
||||||
}, wait)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -21,7 +21,6 @@ import { useRoute, useRouter } from 'vue-router'
|
|||||||
import SearchCard from '@/components/ui/SearchCard.vue'
|
import SearchCard from '@/components/ui/SearchCard.vue'
|
||||||
import { get as getInstance, get_projects as getInstanceProjects } from '@/helpers/profile.js'
|
import { get as getInstance, get_projects as getInstanceProjects } from '@/helpers/profile.js'
|
||||||
import { get_search_results } from '@/helpers/cache.js'
|
import { get_search_results } from '@/helpers/cache.js'
|
||||||
import { debounce } from '@/helpers/utils.js'
|
|
||||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||||
import type Instance from '@/components/ui/Instance.vue'
|
import type Instance from '@/components/ui/Instance.vue'
|
||||||
import InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
|
import InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
|
||||||
@ -190,6 +189,7 @@ const pageCount = computed(() =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
watch(requestParams, () => {
|
watch(requestParams, () => {
|
||||||
|
if (!route.params.projectType) return
|
||||||
refreshSearch()
|
refreshSearch()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -214,45 +214,40 @@ async function refreshSearch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
results.value = rawResults.result
|
results.value = rawResults.result
|
||||||
|
|
||||||
|
const persistentParams: LocationQuery = {}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(route.query)) {
|
||||||
|
if (PERSISTENT_QUERY_PARAMS.includes(key)) {
|
||||||
|
persistentParams[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instanceHideInstalled.value) {
|
||||||
|
persistentParams.ai = 'true'
|
||||||
|
} else {
|
||||||
|
delete persistentParams.ai
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
...persistentParams,
|
||||||
|
...createPageParams(),
|
||||||
|
}
|
||||||
|
|
||||||
|
breadcrumbs.setContext({
|
||||||
|
name: 'Discover content',
|
||||||
|
link: `/browse/${projectType.value}`,
|
||||||
|
query: params,
|
||||||
|
})
|
||||||
|
await router.replace({ path: route.path, query: params })
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPage(newPageNumber: number) {
|
async function setPage(newPageNumber: number) {
|
||||||
currentPage.value = newPageNumber
|
currentPage.value = newPageNumber
|
||||||
|
|
||||||
updateSearchResults()
|
await onSearchChangeToTop()
|
||||||
onSearchChangeToTop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateSearchResults() {
|
|
||||||
await refreshSearch()
|
|
||||||
|
|
||||||
if (import.meta.client) {
|
|
||||||
const persistentParams: LocationQuery = {}
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(route.query)) {
|
|
||||||
if (PERSISTENT_QUERY_PARAMS.includes(key)) {
|
|
||||||
persistentParams[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instanceHideInstalled.value) {
|
|
||||||
persistentParams.ai = 'true'
|
|
||||||
} else {
|
|
||||||
delete persistentParams.ai
|
|
||||||
}
|
|
||||||
|
|
||||||
const params = {
|
|
||||||
...persistentParams,
|
|
||||||
...createPageParams(),
|
|
||||||
}
|
|
||||||
|
|
||||||
await router.replace({ path: route.path, query: params })
|
|
||||||
breadcrumbs.setContext({ name: 'Discover content', link: route.path, query: params })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const debouncedSearchChange = debounce(() => updateSearchResults(1), 200)
|
|
||||||
|
|
||||||
const searchWrapper: Ref<HTMLElement | null> = ref(null)
|
const searchWrapper: Ref<HTMLElement | null> = ref(null)
|
||||||
|
|
||||||
async function onSearchChangeToTop() {
|
async function onSearchChangeToTop() {
|
||||||
@ -261,13 +256,10 @@ async function onSearchChangeToTop() {
|
|||||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function clearSearch() {
|
function clearSearch() {
|
||||||
query.value = ''
|
query.value = ''
|
||||||
await updateSearchResults()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function clearFilters() {}
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => route.params.projectType,
|
() => route.params.projectType,
|
||||||
async (newType) => {
|
async (newType) => {
|
||||||
@ -275,14 +267,9 @@ watch(
|
|||||||
if (!newType || newType === projectType.value) return
|
if (!newType || newType === projectType.value) return
|
||||||
|
|
||||||
projectType.value = newType
|
projectType.value = newType
|
||||||
breadcrumbs.setContext({ name: 'Discover content', link: `/browse/${projectType.value}` })
|
|
||||||
|
|
||||||
currentSortType.value = { display: 'Relevance', name: 'relevance' }
|
currentSortType.value = { display: 'Relevance', name: 'relevance' }
|
||||||
query.value = ''
|
query.value = ''
|
||||||
|
|
||||||
loading.value = true
|
|
||||||
await clearFilters()
|
|
||||||
loading.value = false
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -418,7 +405,6 @@ await refreshSearch()
|
|||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="`Search ${projectType}s...`"
|
:placeholder="`Search ${projectType}s...`"
|
||||||
@input="debouncedSearchChange()"
|
|
||||||
/>
|
/>
|
||||||
<Button v-if="query" class="r-btn" @click="() => clearSearch()">
|
<Button v-if="query" class="r-btn" @click="() => clearSearch()">
|
||||||
<XIcon />
|
<XIcon />
|
||||||
@ -432,7 +418,6 @@ await refreshSearch()
|
|||||||
name="Sort by"
|
name="Sort by"
|
||||||
:options="sortTypes as any"
|
:options="sortTypes as any"
|
||||||
:display-name="(option: SortType | undefined) => option?.display"
|
:display-name="(option: SortType | undefined) => option?.display"
|
||||||
@change="updateSearchResults()"
|
|
||||||
>
|
>
|
||||||
<span class="font-semibold text-primary">Sort by: </span>
|
<span class="font-semibold text-primary">Sort by: </span>
|
||||||
<span class="font-semibold text-secondary">{{ selected }}</span>
|
<span class="font-semibold text-secondary">{{ selected }}</span>
|
||||||
@ -443,7 +428,6 @@ await refreshSearch()
|
|||||||
name="Max results"
|
name="Max results"
|
||||||
:options="[5, 10, 15, 20, 50, 100]"
|
:options="[5, 10, 15, 20, 50, 100]"
|
||||||
class="max-w-[9rem]"
|
class="max-w-[9rem]"
|
||||||
@change="updateSearchResults()"
|
|
||||||
>
|
>
|
||||||
<span class="font-semibold text-primary">View: </span>
|
<span class="font-semibold text-primary">View: </span>
|
||||||
<span class="font-semibold text-secondary">{{ selected }}</span>
|
<span class="font-semibold text-secondary">{{ selected }}</span>
|
||||||
|
|||||||
@ -13,70 +13,77 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #summary> </template>
|
<template #summary> </template>
|
||||||
<template #stats>
|
<template #stats>
|
||||||
<div class="flex items-center gap-2 font-semibold transform capitalize">
|
<div
|
||||||
|
class="flex items-center gap-2 font-semibold transform capitalize border-0 border-solid border-divider pr-4 md:border-r"
|
||||||
|
>
|
||||||
<GameIcon class="h-6 w-6 text-secondary" />
|
<GameIcon class="h-6 w-6 text-secondary" />
|
||||||
{{ instance.loader }} {{ instance.game_version }}
|
{{ instance.loader }} {{ instance.game_version }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center gap-2 font-semibold">
|
||||||
|
<TimerIcon class="h-6 w-6 text-secondary" />
|
||||||
|
<template v-if="timePlayed > 0">
|
||||||
|
{{ timePlayedHumanized }}
|
||||||
|
</template>
|
||||||
|
<template v-else> Never played </template>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<ButtonStyled v-if="instance.install_stage !== 'installed'" color="brand" size="large">
|
<div class="flex gap-2">
|
||||||
<button disabled>Installing...</button>
|
<ButtonStyled v-if="instance.install_stage !== 'installed'" color="brand" size="large">
|
||||||
</ButtonStyled>
|
<button disabled>Installing...</button>
|
||||||
<template v-else>
|
</ButtonStyled>
|
||||||
<div class="flex gap-2">
|
<ButtonStyled v-else-if="playing === true" color="red" size="large">
|
||||||
<ButtonStyled v-if="playing === true" color="red" size="large">
|
<button @click="stopInstance('InstancePage')">
|
||||||
<button @click="stopInstance('InstancePage')">
|
<StopCircleIcon />
|
||||||
<StopCircleIcon />
|
Stop
|
||||||
Stop
|
</button>
|
||||||
</button>
|
</ButtonStyled>
|
||||||
</ButtonStyled>
|
<ButtonStyled
|
||||||
<ButtonStyled
|
v-else-if="playing === false && loading === false"
|
||||||
v-else-if="playing === false && loading === false"
|
color="brand"
|
||||||
color="brand"
|
size="large"
|
||||||
size="large"
|
>
|
||||||
|
<button @click="startInstance('InstancePage')">
|
||||||
|
<PlayIcon />
|
||||||
|
Play
|
||||||
|
</button>
|
||||||
|
</ButtonStyled>
|
||||||
|
<ButtonStyled
|
||||||
|
v-else-if="loading === true && playing === false"
|
||||||
|
color="brand"
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
|
<button disabled>Loading...</button>
|
||||||
|
</ButtonStyled>
|
||||||
|
<ButtonStyled size="large" circular>
|
||||||
|
<RouterLink
|
||||||
|
v-tooltip="'Instance settings'"
|
||||||
|
:to="`/instance/${encodeURIComponent(route.params.id)}/options`"
|
||||||
>
|
>
|
||||||
<button @click="startInstance('InstancePage')">
|
<SettingsIcon />
|
||||||
<PlayIcon />
|
</RouterLink>
|
||||||
Play
|
</ButtonStyled>
|
||||||
</button>
|
<ButtonStyled size="large" type="transparent" circular>
|
||||||
</ButtonStyled>
|
<OverflowMenu
|
||||||
<ButtonStyled
|
:options="[
|
||||||
v-else-if="loading === true && playing === false"
|
{
|
||||||
color="brand"
|
id: 'open-folder',
|
||||||
size="large"
|
action: () => showProfileInFolder(instance.path),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'export-mrpack',
|
||||||
|
action: () => $refs.exportModal.show(),
|
||||||
|
},
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<button disabled>Loading...</button>
|
<MoreVerticalIcon />
|
||||||
</ButtonStyled>
|
<template #share-instance> <UserPlusIcon /> Share instance </template>
|
||||||
<ButtonStyled size="large" circular>
|
<template #host-a-server> <ServerIcon /> Create a server </template>
|
||||||
<RouterLink
|
<template #open-folder> <FolderOpenIcon /> Open folder </template>
|
||||||
v-tooltip="'Instance settings'"
|
<template #export-mrpack> <PackageIcon /> Export modpack </template>
|
||||||
:to="`/instance/${encodeURIComponent(route.params.id)}/options`"
|
</OverflowMenu>
|
||||||
>
|
</ButtonStyled>
|
||||||
<SettingsIcon />
|
</div>
|
||||||
</RouterLink>
|
|
||||||
</ButtonStyled>
|
|
||||||
<ButtonStyled size="large" type="transparent" circular>
|
|
||||||
<OverflowMenu
|
|
||||||
:options="[
|
|
||||||
{
|
|
||||||
id: 'open-folder',
|
|
||||||
action: () => showProfileInFolder(instance.path),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'export-mrpack',
|
|
||||||
action: () => $refs.exportModal.show(),
|
|
||||||
},
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<MoreVerticalIcon />
|
|
||||||
<template #share-instance> <UserPlusIcon /> Share instance </template>
|
|
||||||
<template #host-a-server> <ServerIcon /> Create a server </template>
|
|
||||||
<template #open-folder> <FolderOpenIcon /> Open folder </template>
|
|
||||||
<template #export-mrpack> <PackageIcon /> Export modpack </template>
|
|
||||||
</OverflowMenu>
|
|
||||||
</ButtonStyled>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
</ContentPageHeader>
|
</ContentPageHeader>
|
||||||
</div>
|
</div>
|
||||||
@ -106,15 +113,15 @@
|
|||||||
<ContextMenu ref="options" @option-clicked="handleOptionsClick">
|
<ContextMenu ref="options" @option-clicked="handleOptionsClick">
|
||||||
<template #play> <PlayIcon /> Play </template>
|
<template #play> <PlayIcon /> Play </template>
|
||||||
<template #stop> <StopCircleIcon /> Stop </template>
|
<template #stop> <StopCircleIcon /> Stop </template>
|
||||||
<template #add_content> <PlusIcon /> Add Content </template>
|
<template #add_content> <PlusIcon /> Add content </template>
|
||||||
<template #edit> <EditIcon /> Edit </template>
|
<template #edit> <EditIcon /> Edit </template>
|
||||||
<template #copy_path> <ClipboardCopyIcon /> Copy Path </template>
|
<template #copy_path> <ClipboardCopyIcon /> Copy path </template>
|
||||||
<template #open_folder> <ClipboardCopyIcon /> Open Folder </template>
|
<template #open_folder> <ClipboardCopyIcon /> Open folder </template>
|
||||||
<template #copy_link> <ClipboardCopyIcon /> Copy Link </template>
|
<template #copy_link> <ClipboardCopyIcon /> Copy link </template>
|
||||||
<template #open_link> <ClipboardCopyIcon /> Open In Modrinth <ExternalIcon /> </template>
|
<template #open_link> <ClipboardCopyIcon /> Open in Modrinth <ExternalIcon /> </template>
|
||||||
<template #copy_names><EditIcon />Copy names</template>
|
<template #copy_names><EditIcon />Copy names</template>
|
||||||
<template #copy_slugs><HashIcon />Copy slugs</template>
|
<template #copy_slugs><HashIcon />Copy slugs</template>
|
||||||
<template #copy_links><GlobeIcon />Copy Links</template>
|
<template #copy_links><GlobeIcon />Copy links</template>
|
||||||
<template #toggle><EditIcon />Toggle selected</template>
|
<template #toggle><EditIcon />Toggle selected</template>
|
||||||
<template #disable><XIcon />Disable selected</template>
|
<template #disable><XIcon />Disable selected</template>
|
||||||
<template #enable><CheckCircleIcon />Enable selected</template>
|
<template #enable><CheckCircleIcon />Enable selected</template>
|
||||||
@ -153,8 +160,9 @@ import {
|
|||||||
UpdatedIcon,
|
UpdatedIcon,
|
||||||
MoreVerticalIcon,
|
MoreVerticalIcon,
|
||||||
GameIcon,
|
GameIcon,
|
||||||
|
TimerIcon,
|
||||||
} from '@modrinth/assets'
|
} from '@modrinth/assets'
|
||||||
import { get, kill, run } from '@/helpers/profile'
|
import { get, get_full_path, kill, run } from '@/helpers/profile'
|
||||||
import { get_by_profile_path } from '@/helpers/process'
|
import { get_by_profile_path } from '@/helpers/process'
|
||||||
import { process_listener, profile_listener } from '@/helpers/events'
|
import { process_listener, profile_listener } from '@/helpers/events'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
@ -168,8 +176,13 @@ import { convertFileSrc } from '@tauri-apps/api/core'
|
|||||||
import { handleSevereError } from '@/store/error.js'
|
import { handleSevereError } from '@/store/error.js'
|
||||||
import { get_project, get_version_many } from '@/helpers/cache.js'
|
import { get_project, get_version_many } from '@/helpers/cache.js'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
import duration from 'dayjs/plugin/duration'
|
||||||
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||||
import ExportModal from '@/components/ui/ExportModal.vue'
|
import ExportModal from '@/components/ui/ExportModal.vue'
|
||||||
|
|
||||||
|
dayjs.extend(duration)
|
||||||
|
dayjs.extend(relativeTime)
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -321,9 +334,11 @@ const handleOptionsClick = async (args) => {
|
|||||||
case 'open_folder':
|
case 'open_folder':
|
||||||
await showProfileInFolder(instance.value.path)
|
await showProfileInFolder(instance.value.path)
|
||||||
break
|
break
|
||||||
case 'copy_path':
|
case 'copy_path': {
|
||||||
await navigator.clipboard.writeText(instance.value.path)
|
const fullPath = await get_full_path(instance.value.path)
|
||||||
|
await navigator.clipboard.writeText(fullPath)
|
||||||
break
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,6 +362,26 @@ const icon = computed(() =>
|
|||||||
instance.value.icon_path ? convertFileSrc(instance.value.icon_path) : null,
|
instance.value.icon_path ? convertFileSrc(instance.value.icon_path) : null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const timePlayed = computed(() => {
|
||||||
|
return instance.value.recent_time_played + instance.value.submitted_time_played
|
||||||
|
})
|
||||||
|
|
||||||
|
const timePlayedHumanized = computed(() => {
|
||||||
|
const duration = dayjs.duration(timePlayed.value, 'seconds')
|
||||||
|
const hours = Math.floor(duration.asHours())
|
||||||
|
if (hours >= 1) {
|
||||||
|
return hours + ' hour' + (hours > 1 ? 's' : '')
|
||||||
|
}
|
||||||
|
|
||||||
|
const minutes = Math.floor(duration.asMinutes())
|
||||||
|
if (minutes >= 1) {
|
||||||
|
return minutes + ' minute' + (minutes > 1 ? 's' : '')
|
||||||
|
}
|
||||||
|
|
||||||
|
const seconds = Math.floor(duration.asSeconds())
|
||||||
|
return seconds + ' second' + (seconds > 1 ? 's' : '')
|
||||||
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
unlistenProcesses()
|
unlistenProcesses()
|
||||||
unlistenProfiles()
|
unlistenProfiles()
|
||||||
|
|||||||
@ -183,8 +183,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'copy-link',
|
id: 'copy-link',
|
||||||
shown: item.project !== undefined,
|
shown: item.data !== undefined && item.data.slug !== undefined,
|
||||||
action: () => toggleDisableMod(item.data),
|
action: () => copyModLink(item),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
divider: true,
|
divider: true,
|
||||||
@ -674,6 +674,12 @@ const removeMod = async (mod) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const copyModLink = async (mod) => {
|
||||||
|
await navigator.clipboard.writeText(
|
||||||
|
`https://modrinth.com/${mod.data.project_type}/${mod.data.slug}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const deleteSelected = async () => {
|
const deleteSelected = async () => {
|
||||||
for (const project of functionValues.value) {
|
for (const project of functionValues.value) {
|
||||||
await remove_project(props.instance.path, project.path).catch(handleError)
|
await remove_project(props.instance.path, project.path).catch(handleError)
|
||||||
|
|||||||
@ -149,9 +149,9 @@ export default new createRouter({
|
|||||||
linkExactActiveClass: 'router-link-exact-active',
|
linkExactActiveClass: 'router-link-exact-active',
|
||||||
scrollBehavior() {
|
scrollBehavior() {
|
||||||
// Sometimes Vue's scroll behavior is not working as expected, so we need to manually scroll to top (especially on Linux)
|
// Sometimes Vue's scroll behavior is not working as expected, so we need to manually scroll to top (especially on Linux)
|
||||||
document.querySelector('.router-view')?.scrollTo(0, 0)
|
document.querySelector('.app-viewport')?.scrollTo(0, 0)
|
||||||
return {
|
return {
|
||||||
el: '.router-view',
|
el: '.app-viewport',
|
||||||
top: 0,
|
top: 0,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -16,7 +16,7 @@ theseus = { path = "../../packages/app-lib", features = ["tauri"] }
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
|
||||||
tauri = { version = "2.1.1", features = ["devtools", "macos-private-api", "protocol-asset", "unstable"] }
|
tauri = { git = "https://github.com/modrinth/tauri", rev = "9c36dd3", features = ["devtools", "macos-private-api", "protocol-asset", "unstable"] }
|
||||||
tauri-plugin-window-state = "2.2.0"
|
tauri-plugin-window-state = "2.2.0"
|
||||||
tauri-plugin-deep-link = "2.2.0"
|
tauri-plugin-deep-link = "2.2.0"
|
||||||
tauri-plugin-os = "2.2.0"
|
tauri-plugin-os = "2.2.0"
|
||||||
|
|||||||
@ -103,7 +103,7 @@ pub async fn init_ads_window<R: Runtime>(
|
|||||||
AD_LINK.parse().unwrap(),
|
AD_LINK.parse().unwrap(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.initialization_script(LINK_SCRIPT)
|
.initialization_script_for_main_only(LINK_SCRIPT, false)
|
||||||
.user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36")
|
.user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36")
|
||||||
.zoom_hotkeys_enabled(false)
|
.zoom_hotkeys_enabled(false)
|
||||||
.transparent(true),
|
.transparent(true),
|
||||||
|
|||||||
@ -42,9 +42,7 @@
|
|||||||
Install content to server
|
Install content to server
|
||||||
</h1>
|
</h1>
|
||||||
</template>
|
</template>
|
||||||
<ContentPageHeader v-else>
|
<ContentPageHeader v-else></ContentPageHeader>
|
||||||
<template #title> Discover content </template>
|
|
||||||
</ContentPageHeader>
|
|
||||||
<NavTabs v-if="!server" :links="selectableProjectTypes" class="hidden md:flex" />
|
<NavTabs v-if="!server" :links="selectableProjectTypes" class="hidden md:flex" />
|
||||||
</section>
|
</section>
|
||||||
<aside
|
<aside
|
||||||
@ -342,7 +340,11 @@ const tags = useTags();
|
|||||||
const flags = useFeatureFlags();
|
const flags = useFeatureFlags();
|
||||||
const auth = await useAuth();
|
const auth = await useAuth();
|
||||||
|
|
||||||
const projectType = ref({ id: "mod", display: "mod", actual: "mod" });
|
const projectType = computed(() =>
|
||||||
|
tags.value.projectTypes.find(
|
||||||
|
(x) => x.id === route.path.replaceAll(/^\/|s\/?$/g, ""), // Removes prefix `/` and suffixes `s` and `s/`
|
||||||
|
),
|
||||||
|
);
|
||||||
const projectTypes = computed(() => [projectType.value.id]);
|
const projectTypes = computed(() => [projectType.value.id]);
|
||||||
|
|
||||||
const server = ref();
|
const server = ref();
|
||||||
@ -506,10 +508,6 @@ async function serverInstall(project) {
|
|||||||
project.installing = false;
|
project.installing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
projectType.value = tags.value.projectTypes.find(
|
|
||||||
(x) => x.id === route.path.replaceAll(/^\/|s\/?$/g, ""), // Removes prefix `/` and suffixes `s` and `s/`
|
|
||||||
);
|
|
||||||
|
|
||||||
const noLoad = ref(false);
|
const noLoad = ref(false);
|
||||||
const {
|
const {
|
||||||
data: rawResults,
|
data: rawResults,
|
||||||
|
|||||||
@ -118,7 +118,7 @@ pub async fn profile_create(
|
|||||||
&state.file_watcher,
|
&state.file_watcher,
|
||||||
&state.directories,
|
&state.directories,
|
||||||
)
|
)
|
||||||
.await?;
|
.await;
|
||||||
|
|
||||||
profile.upsert(&state.pool).await?;
|
profile.upsert(&state.pool).await?;
|
||||||
|
|
||||||
|
|||||||
@ -87,7 +87,7 @@ pub async fn init_watcher() -> crate::Result<FileWatcher> {
|
|||||||
pub(crate) async fn watch_profiles_init(
|
pub(crate) async fn watch_profiles_init(
|
||||||
watcher: &FileWatcher,
|
watcher: &FileWatcher,
|
||||||
dirs: &DirectoryInfo,
|
dirs: &DirectoryInfo,
|
||||||
) -> crate::Result<()> {
|
) {
|
||||||
if let Ok(profiles_dir) = std::fs::read_dir(dirs.profiles_dir()) {
|
if let Ok(profiles_dir) = std::fs::read_dir(dirs.profiles_dir()) {
|
||||||
for profile_dir in profiles_dir {
|
for profile_dir in profiles_dir {
|
||||||
if let Ok(file_name) = profile_dir.map(|x| x.file_name()) {
|
if let Ok(file_name) = profile_dir.map(|x| x.file_name()) {
|
||||||
@ -96,20 +96,18 @@ pub(crate) async fn watch_profiles_init(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
watch_profile(file_name, watcher, dirs).await?;
|
watch_profile(file_name, watcher, dirs).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn watch_profile(
|
pub(crate) async fn watch_profile(
|
||||||
profile_path: &str,
|
profile_path: &str,
|
||||||
watcher: &FileWatcher,
|
watcher: &FileWatcher,
|
||||||
dirs: &DirectoryInfo,
|
dirs: &DirectoryInfo,
|
||||||
) -> crate::Result<()> {
|
) {
|
||||||
let profile_path = dirs.profiles_dir().join(profile_path);
|
let profile_path = dirs.profiles_dir().join(profile_path);
|
||||||
|
|
||||||
if profile_path.exists() && profile_path.is_dir() {
|
if profile_path.exists() && profile_path.is_dir() {
|
||||||
@ -120,15 +118,25 @@ pub(crate) async fn watch_profile(
|
|||||||
let path = profile_path.join(folder);
|
let path = profile_path.join(folder);
|
||||||
|
|
||||||
if !path.exists() && !path.is_symlink() {
|
if !path.exists() && !path.is_symlink() {
|
||||||
crate::util::io::create_dir_all(&path).await?;
|
if let Err(e) = crate::util::io::create_dir_all(&path).await {
|
||||||
|
tracing::error!(
|
||||||
|
"Failed to create directory for watcher {path:?}: {e}"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut watcher = watcher.write().await;
|
let mut watcher = watcher.write().await;
|
||||||
watcher.watcher().watch(&path, RecursiveMode::Recursive)?;
|
if let Err(e) =
|
||||||
|
watcher.watcher().watch(&path, RecursiveMode::Recursive)
|
||||||
|
{
|
||||||
|
tracing::error!(
|
||||||
|
"Failed to watch directory for watcher {path:?}: {e}"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn crash_task(path: String) {
|
fn crash_task(path: String) {
|
||||||
|
|||||||
@ -146,7 +146,7 @@ impl State {
|
|||||||
let discord_rpc = DiscordGuard::init()?;
|
let discord_rpc = DiscordGuard::init()?;
|
||||||
|
|
||||||
let file_watcher = fs_watcher::init_watcher().await?;
|
let file_watcher = fs_watcher::init_watcher().await?;
|
||||||
fs_watcher::watch_profiles_init(&file_watcher, &directories).await?;
|
fs_watcher::watch_profiles_init(&file_watcher, &directories).await;
|
||||||
|
|
||||||
let process_manager = ProcessManager::new();
|
let process_manager = ProcessManager::new();
|
||||||
|
|
||||||
|
|||||||
1
packages/assets/icons/timer.svg
Normal file
1
packages/assets/icons/timer.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="10" x2="14" y1="2" y2="2"/><line x1="12" x2="15" y1="14" y2="11"/><circle cx="12" cy="14" r="8"/></svg>
|
||||||
|
After Width: | Height: | Size: 295 B |
@ -180,6 +180,7 @@ import _CPUIcon from './icons/cpu.svg?component'
|
|||||||
import _DBIcon from './icons/db.svg?component'
|
import _DBIcon from './icons/db.svg?component'
|
||||||
import _LoaderIcon from './icons/loader.svg?component'
|
import _LoaderIcon from './icons/loader.svg?component'
|
||||||
import _ImportIcon from './icons/import.svg?component'
|
import _ImportIcon from './icons/import.svg?component'
|
||||||
|
import _TimerIcon from './icons/timer.svg?component'
|
||||||
|
|
||||||
// Editor Icons
|
// Editor Icons
|
||||||
import _BoldIcon from './icons/bold.svg?component'
|
import _BoldIcon from './icons/bold.svg?component'
|
||||||
@ -381,3 +382,4 @@ export const DBIcon = _DBIcon
|
|||||||
export const LoaderIcon = _LoaderIcon
|
export const LoaderIcon = _LoaderIcon
|
||||||
export const ImportIcon = _ImportIcon
|
export const ImportIcon = _ImportIcon
|
||||||
export const CardIcon = _CardIcon
|
export const CardIcon = _CardIcon
|
||||||
|
export const TimerIcon = _TimerIcon
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
ref="dropdown"
|
ref="dropdown"
|
||||||
no-auto-focus
|
no-auto-focus
|
||||||
:aria-id="dropdownId || null"
|
:aria-id="dropdownId || null"
|
||||||
@hide="focusTrigger"
|
@apply-hide="focusTrigger"
|
||||||
@apply-show="focusMenuChild"
|
@apply-show="focusMenuChild"
|
||||||
>
|
>
|
||||||
<button ref="trigger" v-bind="$attrs" v-tooltip="tooltip">
|
<button ref="trigger" v-bind="$attrs" v-tooltip="tooltip">
|
||||||
|
|||||||
@ -83,7 +83,7 @@ function setSelected(value: boolean) {
|
|||||||
<ContentListItem
|
<ContentListItem
|
||||||
v-model="selectionStates[ref.filename]"
|
v-model="selectionStates[ref.filename]"
|
||||||
:item="ref"
|
:item="ref"
|
||||||
:last="false"
|
:last="ref === items.length - 1"
|
||||||
class="mb-2"
|
class="mb-2"
|
||||||
@update:model-value="updateSelection"
|
@update:model-value="updateSelection"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -534,6 +534,10 @@ export function useSearch(
|
|||||||
currentPage.value = Number(page)
|
currentPage.value = Number(page)
|
||||||
readParams.add('page')
|
readParams.add('page')
|
||||||
})
|
})
|
||||||
|
loadQueryParam(['q'], (queryVal) => {
|
||||||
|
query.value = String(queryVal)
|
||||||
|
readParams.add('q')
|
||||||
|
})
|
||||||
|
|
||||||
for (const key of Object.keys(route.query).filter((key) => !readParams.has(key))) {
|
for (const key of Object.keys(route.query).filter((key) => !readParams.has(key))) {
|
||||||
const type = filters.value.find((type) => type.query_param === key)
|
const type = filters.value.find((type) => type.query_param === key)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user