v0.9.1 fixes
This commit is contained in:
parent
5b00ac17e5
commit
4a031f7bbd
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -8956,7 +8956,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "theseus"
|
||||
version = "0.9.0"
|
||||
version = "0.9.1"
|
||||
dependencies = [
|
||||
"async-recursion",
|
||||
"async-tungstenite",
|
||||
@ -9007,7 +9007,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "theseus_gui"
|
||||
version = "0.9.0"
|
||||
version = "0.9.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"cocoa 0.25.0",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@modrinth/app-frontend",
|
||||
"private": true,
|
||||
"version": "0.9.0",
|
||||
"version": "0.9.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@ -16,6 +16,7 @@ import {
|
||||
RestoreIcon,
|
||||
LogOutIcon,
|
||||
RightArrowIcon,
|
||||
LeftArrowIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Avatar, Button, ButtonStyled, Notifications, OverflowMenu } from '@modrinth/ui'
|
||||
import { useLoading, useTheming } from '@/store/state'
|
||||
@ -256,25 +257,19 @@ themeStore.$subscribe(() => {
|
||||
sidebarToggled.value = !themeStore.toggleSidebar
|
||||
})
|
||||
|
||||
const forceSidebar = ref(false)
|
||||
const forceSidebar = computed(
|
||||
() => route.path.startsWith('/browse') || route.path.startsWith('/project'),
|
||||
)
|
||||
const sidebarVisible = computed(() => sidebarToggled.value || forceSidebar.value)
|
||||
const showAd = computed(() => !(!sidebarVisible.value || hasPlus.value))
|
||||
|
||||
router.afterEach((to) => {
|
||||
forceSidebar.value = to.path.startsWith('/browse') || to.path.startsWith('/project')
|
||||
})
|
||||
|
||||
const currentTimeout = ref(null)
|
||||
watch(
|
||||
showAd,
|
||||
() => {
|
||||
if (!showAd.value) {
|
||||
if (currentTimeout.value) clearTimeout(currentTimeout.value)
|
||||
hide_ads_window(true)
|
||||
} else {
|
||||
currentTimeout.value = setTimeout(() => {
|
||||
init_ads_window(true)
|
||||
}, 400)
|
||||
init_ads_window(true)
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
@ -443,6 +438,20 @@ function handleAuxClick(e) {
|
||||
<div data-tauri-drag-region class="app-grid-statusbar bg-bg-raised h-[--top-bar-height] flex">
|
||||
<div data-tauri-drag-region class="flex p-3">
|
||||
<ModrinthAppLogo class="h-full w-auto text-contrast pointer-events-none" />
|
||||
<div class="flex items-center gap-1 ml-3">
|
||||
<button
|
||||
class="cursor-pointer p-0 m-0 border-none outline-none bg-button-bg rounded-full flex items-center justify-center w-6 h-6 hover:brightness-75 transition-all"
|
||||
@click="router.back()"
|
||||
>
|
||||
<LeftArrowIcon />
|
||||
</button>
|
||||
<button
|
||||
class="cursor-pointer p-0 m-0 border-none outline-none bg-button-bg rounded-full flex items-center justify-center w-6 h-6 hover:brightness-75 transition-all"
|
||||
@click="router.forward()"
|
||||
>
|
||||
<RightArrowIcon />
|
||||
</button>
|
||||
</div>
|
||||
<Breadcrumbs class="pt-[2px]" />
|
||||
</div>
|
||||
<section class="flex ml-auto items-center">
|
||||
@ -704,7 +713,7 @@ function handleAuxClick(e) {
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 0px;
|
||||
transition: grid-template-columns 0.4s ease-in-out;
|
||||
// transition: grid-template-columns 0.4s ease-in-out;
|
||||
|
||||
&.sidebar-enabled {
|
||||
grid-template-columns: 1fr 300px;
|
||||
|
||||
@ -35,10 +35,12 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const playing = ref(false)
|
||||
|
||||
const loading = ref(false)
|
||||
const modLoading = computed(
|
||||
() =>
|
||||
currentEvent.value === 'installing' || (currentEvent.value === 'launched' && !playing.value),
|
||||
loading.value ||
|
||||
currentEvent.value === 'installing' ||
|
||||
(currentEvent.value === 'launched' && !playing.value),
|
||||
)
|
||||
const installing = computed(() => props.instance.install_stage !== 'installed')
|
||||
|
||||
@ -56,6 +58,7 @@ const checkProcess = async () => {
|
||||
|
||||
const play = async (e, context) => {
|
||||
e?.stopPropagation()
|
||||
loading.value = true
|
||||
await run(props.instance.path)
|
||||
.catch((err) => handleSevereError(err, { profilePath: props.instance.path }))
|
||||
.finally(() => {
|
||||
@ -65,6 +68,7 @@ const play = async (e, context) => {
|
||||
source: context,
|
||||
})
|
||||
})
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const stop = async (e, context) => {
|
||||
@ -118,7 +122,7 @@ onUnmounted(() => unlisten())
|
||||
<template>
|
||||
<template v-if="compact">
|
||||
<div
|
||||
class="button-base card-shadow grid grid-cols-[auto_1fr_auto] bg-bg-raised rounded-xl p-3 pl-4 gap-2 cursor-pointer active:scale-[0.98] transition-transform"
|
||||
class="card-shadow grid grid-cols-[auto_1fr_auto] bg-bg-raised rounded-xl p-3 pl-4 gap-2 cursor-pointer hover:brightness-90 transition-all"
|
||||
@click="seeInstance"
|
||||
@mouseenter="checkProcess"
|
||||
>
|
||||
|
||||
@ -60,7 +60,7 @@ const toTransparent = computed(() => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="card-shadow button-base bg-bg-raised rounded-xl overflow-clip cursor-pointer active:scale-[0.98] transition-transform"
|
||||
class="card-shadow bg-bg-raised rounded-xl overflow-clip cursor-pointer hover:brightness-90 transition-all"
|
||||
@click="router.push(`/project/${project.slug}`)"
|
||||
>
|
||||
<div
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ChevronRightIcon } from '@modrinth/assets'
|
||||
import { init_ads_window, open_ads_link, record_ads_click } from '@/helpers/ads.js'
|
||||
import { init_ads_window } from '@/helpers/ads.js'
|
||||
|
||||
const adsWrapper = ref(null)
|
||||
|
||||
@ -29,27 +28,12 @@ function updateAdPosition() {
|
||||
initDevicePixelRatioWatcher()
|
||||
}
|
||||
}
|
||||
|
||||
async function openPlusLink() {
|
||||
await record_ads_click()
|
||||
await open_ads_link('https://modrinth.com/plus', 'https://modrinth.com')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="adsWrapper" class="ad-parent relative flex w-full justify-center cursor-pointer bg-bg">
|
||||
<div class="flex max-h-[250px] min-h-[250px] min-w-[300px] max-w-[300px] flex-col gap-4 p-6">
|
||||
<p class="m-0 text-2xl font-bold text-contrast">75% of ad revenue goes to creators</p>
|
||||
<button
|
||||
class="mt-auto items-center gap-1 text-purple hover:underline bg-transparent border-none text-left cursor-pointer outline-none"
|
||||
@click="openPlusLink"
|
||||
>
|
||||
<span>
|
||||
Support creators and Modrinth ad-free with
|
||||
<span class="font-bold">Modrinth+</span>
|
||||
</span>
|
||||
<ChevronRightIcon class="relative top-[3px] h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="card-shadow button-base p-4 bg-bg-raised rounded-xl flex gap-3 group"
|
||||
class="card-shadow p-4 bg-bg-raised rounded-xl flex gap-3 group cursor-pointer hover:brightness-90 transition-all"
|
||||
@click="
|
||||
() => {
|
||||
emit('open')
|
||||
@ -12,21 +12,7 @@
|
||||
"
|
||||
>
|
||||
<div class="icon w-[96px] h-[96px] relative">
|
||||
<Avatar
|
||||
:src="project.icon_url"
|
||||
size="96px"
|
||||
class="search-icon origin-top transition-all"
|
||||
:class="{ 'scale-[0.85]': installed, 'brightness-50': installing }"
|
||||
/>
|
||||
<div v-if="installing" class="rounded-2xl absolute inset-0 flex items-center justify-center">
|
||||
<SpinnerIcon class="h-8 w-8 animate-spin" />
|
||||
</div>
|
||||
<div
|
||||
v-if="installed"
|
||||
class="absolute shadow-sm font-semibold bottom-0 w-full p-1 bg-button-bg rounded-full text-xs justify-center items-center flex gap-1 text-brand border-[1px] border-solid border-[--color-button-border]"
|
||||
>
|
||||
<CheckIcon class="shrink-0 stroke-[3px]" /> Installed
|
||||
</div>
|
||||
<Avatar :src="project.icon_url" size="96px" class="search-icon origin-top transition-all" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 overflow-hidden">
|
||||
<div class="gap-2 overflow-hidden no-wrap text-ellipsis">
|
||||
@ -40,6 +26,42 @@
|
||||
</div>
|
||||
<div v-if="categories.length > 0" class="mt-auto flex items-center gap-1 no-wrap">
|
||||
<TagsIcon class="h-4 w-4 shrink-0" />
|
||||
<div
|
||||
v-if="project.project_type === 'mod' || project.project_type === 'modpack'"
|
||||
class="text-sm font-semibold text-secondary flex gap-1 px-[0.375rem] py-0.5 bg-button-bg rounded-full"
|
||||
>
|
||||
<template v-if="project.client_side === 'optional' && project.server_side === 'optional'">
|
||||
Client or server
|
||||
</template>
|
||||
<template
|
||||
v-else-if="
|
||||
(project.client_side === 'optional' || project.client_side === 'required') &&
|
||||
(project.server_side === 'optional' || project.server_side === 'unsupported')
|
||||
"
|
||||
>
|
||||
Client
|
||||
</template>
|
||||
<template
|
||||
v-else-if="
|
||||
(project.server_side === 'optional' || project.server_side === 'required') &&
|
||||
(project.client_side === 'optional' || project.client_side === 'unsupported')
|
||||
"
|
||||
>
|
||||
Server
|
||||
</template>
|
||||
<template
|
||||
v-else-if="
|
||||
project.client_side === 'unsupported' && project.server_side === 'unsupported'
|
||||
"
|
||||
>
|
||||
Unsupported
|
||||
</template>
|
||||
<template
|
||||
v-else-if="project.client_side === 'required' && project.server_side === 'required'"
|
||||
>
|
||||
Client and server
|
||||
</template>
|
||||
</div>
|
||||
<div
|
||||
v-for="tag in categories"
|
||||
:key="tag"
|
||||
@ -65,19 +87,8 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="mt-auto relative">
|
||||
<div
|
||||
class="flex items-center gap-2 group-hover:-translate-y-3 group-hover:opacity-0 group-focus-within:opacity-0 group-hover:scale-95 group-focus-within:scale-95 transition-all"
|
||||
>
|
||||
<HistoryIcon class="shrink-0" />
|
||||
<span>
|
||||
<span class="text-secondary">Updated</span>
|
||||
{{ dayjs(project.date_modified ?? project.updated).fromNow() }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="opacity-0 scale-95 translate-y-3 group-hover:translate-y-0 group-hover:scale-100 group-hover:opacity-100 group-focus-within:opacity-100 group-focus-within:scale-100 absolute bottom-0 right-0 transition-all w-fit"
|
||||
>
|
||||
<ButtonStyled color="brand">
|
||||
<div class="absolute bottom-0 right-0 w-fit">
|
||||
<ButtonStyled color="brand" type="outlined">
|
||||
<button
|
||||
:disabled="installed || installing"
|
||||
class="shrink-0 no-wrap"
|
||||
@ -106,15 +117,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
SpinnerIcon,
|
||||
TagsIcon,
|
||||
DownloadIcon,
|
||||
HeartIcon,
|
||||
PlusIcon,
|
||||
CheckIcon,
|
||||
HistoryIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { TagsIcon, DownloadIcon, HeartIcon, PlusIcon, CheckIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, Avatar } from '@modrinth/ui'
|
||||
import { formatNumber, formatCategory } from '@modrinth/utils'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
@ -356,12 +356,6 @@ const messages = defineMessages({
|
||||
const options = ref(null)
|
||||
const handleRightClick = (event, result) => {
|
||||
options.value.showMenu(event, result, [
|
||||
{
|
||||
name: 'install',
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
name: 'open_link',
|
||||
},
|
||||
|
||||
@ -176,15 +176,18 @@
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<div v-else class="w-[36px]"></div>
|
||||
<Toggle
|
||||
class="!mx-2"
|
||||
:model-value="!item.data.disabled"
|
||||
:checked="!item.data.disabled"
|
||||
@update:model-value="toggleDisableMod(item.data)"
|
||||
/>
|
||||
<ButtonStyled type="transparent" circular>
|
||||
<button
|
||||
v-tooltip="item.disabled ? `Enable` : `Disable`"
|
||||
@click="toggleDisableMod(item.data)"
|
||||
>
|
||||
<CheckCircleIcon v-if="item.disabled" />
|
||||
<SlashIcon v-else />
|
||||
<button v-tooltip="'Remove'" @click="removeMod(item)">
|
||||
<TrashIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
|
||||
<ButtonStyled type="transparent" circular>
|
||||
<OverflowMenu
|
||||
:options="[
|
||||
@ -197,23 +200,12 @@
|
||||
shown: item.data !== undefined && item.data.slug !== undefined,
|
||||
action: () => copyModLink(item),
|
||||
},
|
||||
{
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
id: 'remove',
|
||||
color: 'red',
|
||||
action: () => removeMod(item),
|
||||
},
|
||||
]"
|
||||
direction="left"
|
||||
>
|
||||
<MoreVerticalIcon />
|
||||
<template #show-file> <ExternalIcon /> Show file </template>
|
||||
<template #copy-link> <ClipboardCopyIcon /> Copy link </template>
|
||||
<template v-if="item.disabled" #toggle> <CheckCircleIcon /> Enable </template>
|
||||
<template v-else #toggle> <SlashIcon /> Disable </template>
|
||||
<template #remove> <TrashIcon /> Remove </template>
|
||||
</OverflowMenu>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
@ -275,7 +267,14 @@ import {
|
||||
UpdatedIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Button, ButtonStyled, ContentListPanel, OverflowMenu, Pagination } from '@modrinth/ui'
|
||||
import {
|
||||
Button,
|
||||
ButtonStyled,
|
||||
ContentListPanel,
|
||||
OverflowMenu,
|
||||
Pagination,
|
||||
Toggle,
|
||||
} from '@modrinth/ui'
|
||||
import { formatProjectType } from '@modrinth/utils'
|
||||
import type { ComputedRef } from 'vue'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
@ -462,6 +461,10 @@ const messages = defineMessages({
|
||||
id: 'instance.filter.updates-available',
|
||||
defaultMessage: 'Updates available',
|
||||
},
|
||||
disabledFilter: {
|
||||
id: 'instance.filter.disabled',
|
||||
defaultMessage: 'Disabled projects',
|
||||
},
|
||||
})
|
||||
|
||||
const filterOptions: ComputedRef<FilterOption[]> = computed(() => {
|
||||
@ -488,19 +491,30 @@ const filterOptions: ComputedRef<FilterOption[]> = computed(() => {
|
||||
})
|
||||
}
|
||||
|
||||
if (projects.value.some((m) => m.disabled)) {
|
||||
options.push({
|
||||
id: 'disabled',
|
||||
formattedName: formatMessage(messages.disabledFilter),
|
||||
})
|
||||
}
|
||||
|
||||
return options
|
||||
})
|
||||
|
||||
const selectedFilters = ref([])
|
||||
const filteredProjects = computed(() => {
|
||||
const updatesFilter = selectedFilters.value.includes('updates')
|
||||
const disabledFilter = selectedFilters.value.includes('disabled')
|
||||
|
||||
const typeFilters = selectedFilters.value.filter((filter) => filter !== 'updates')
|
||||
const typeFilters = selectedFilters.value.filter(
|
||||
(filter) => filter !== 'updates' && filter !== 'disabled',
|
||||
)
|
||||
|
||||
return projects.value.filter((project) => {
|
||||
return (
|
||||
(typeFilters.length === 0 || typeFilters.includes(project.project_type)) &&
|
||||
(!updatesFilter || project.outdated)
|
||||
(!updatesFilter || project.outdated) &&
|
||||
(!disabledFilter || project.disabled)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "theseus_gui"
|
||||
version = "0.9.0"
|
||||
version = "0.9.1"
|
||||
description = "The Modrinth App is a desktop application for managing your Minecraft mods"
|
||||
license = "GPL-3.0-only"
|
||||
repository = "https://github.com/modrinth/code/apps/app/"
|
||||
|
||||
@ -21,3 +21,86 @@ document.addEventListener(
|
||||
window.open = (url, target, features) => {
|
||||
window.top.postMessage({ modrinthOpenUrl: url }, 'https://modrinth.com')
|
||||
}
|
||||
|
||||
function muteAudioContext() {
|
||||
if (window.AudioContext || window.webkitAudioContext) {
|
||||
const AudioContext = window.AudioContext || window.webkitAudioContext
|
||||
const originalCreateMediaElementSource = AudioContext.prototype.createMediaElementSource
|
||||
const originalCreateMediaStreamSource = AudioContext.prototype.createMediaStreamSource
|
||||
const originalCreateMediaStreamTrackSource = AudioContext.prototype.createMediaStreamTrackSource
|
||||
const originalCreateBufferSource = AudioContext.prototype.createBufferSource
|
||||
const originalCreateOscillator = AudioContext.prototype.createOscillator
|
||||
|
||||
AudioContext.prototype.createGain = function () {
|
||||
const gain = originalCreateGain.call(this)
|
||||
gain.gain.value = 0
|
||||
return gain
|
||||
}
|
||||
|
||||
AudioContext.prototype.createMediaElementSource = function (mediaElement) {
|
||||
const source = originalCreateMediaElementSource.call(this, mediaElement)
|
||||
source.connect(this.createGain())
|
||||
return source
|
||||
}
|
||||
|
||||
AudioContext.prototype.createMediaStreamSource = function (mediaStream) {
|
||||
const source = originalCreateMediaStreamSource.call(this, mediaStream)
|
||||
source.connect(this.createGain())
|
||||
return source
|
||||
}
|
||||
|
||||
AudioContext.prototype.createMediaStreamTrackSource = function (mediaStreamTrack) {
|
||||
const source = originalCreateMediaStreamTrackSource.call(this, mediaStreamTrack)
|
||||
source.connect(this.createGain())
|
||||
return source
|
||||
}
|
||||
|
||||
AudioContext.prototype.createBufferSource = function () {
|
||||
const source = originalCreateBufferSource.call(this)
|
||||
source.connect(this.createGain())
|
||||
return source
|
||||
}
|
||||
|
||||
AudioContext.prototype.createOscillator = function () {
|
||||
const oscillator = originalCreateOscillator.call(this)
|
||||
oscillator.connect(this.createGain())
|
||||
return oscillator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function muteVideo(mediaElement) {
|
||||
let count = Number(mediaElement.getAttribute('data-modrinth-muted-count') ?? 0)
|
||||
|
||||
if (!mediaElement.muted || mediaElement.volume !== 0) {
|
||||
mediaElement.muted = true
|
||||
mediaElement.volume = 0
|
||||
|
||||
mediaElement.setAttribute('data-modrinth-muted-count', count + 1)
|
||||
}
|
||||
|
||||
if (count > 5) {
|
||||
// Video is detected as malicious, so it is removed from the page
|
||||
mediaElement.remove()
|
||||
}
|
||||
}
|
||||
|
||||
function muteVideos() {
|
||||
document.querySelectorAll('video, audio').forEach(function (mediaElement) {
|
||||
muteVideo(mediaElement)
|
||||
|
||||
if (!mediaElement.hasAttribute('data-modrinth-muted')) {
|
||||
mediaElement.addEventListener('volumechange', () => muteVideo(mediaElement))
|
||||
|
||||
mediaElement.setAttribute('data-modrinth-muted', 'true')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
muteVideos()
|
||||
muteAudioContext()
|
||||
|
||||
const observer = new MutationObserver(muteVideos)
|
||||
observer.observe(document.body, { childList: true, subtree: true })
|
||||
})
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
]
|
||||
},
|
||||
"productName": "Modrinth App",
|
||||
"version": "0.9.0",
|
||||
"version": "0.9.1",
|
||||
"mainBinaryName": "Modrinth App",
|
||||
"identifier": "ModrinthApp",
|
||||
"plugins": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "theseus"
|
||||
version = "0.9.0"
|
||||
version = "0.9.1"
|
||||
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ const model = defineModel<boolean>()
|
||||
</div>
|
||||
<div class="text-secondary text-xs line-clamp-1 break-all">{{ item.filename }}</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-1">
|
||||
<div class="flex justify-end gap-1 items-center">
|
||||
<slot name="actions" :item="item" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
</section>
|
||||
<section
|
||||
v-if="
|
||||
(project.actualProjectType === 'mod' || project.project_type === 'modpack') &&
|
||||
(project.project_type === 'mod' || project.project_type === 'modpack') &&
|
||||
!(project.client_side === 'unsupported' && project.server_side === 'unsupported') &&
|
||||
!(project.client_side === 'unknown' && project.server_side === 'unknown')
|
||||
"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user