mirror of
https://github.com/modrinth/code.git
synced 2026-08-27 01:54:47 +00:00
* feat: implement instance share page + search_users backend call * feat: invite players modal * feat: use tanstack queries for friends sync across app pages * feat: base shared instances implementation * fix: admon style * feat: impl instance admonitions like server panel * fix: impl get + del usage * feat: support modpack links * feat: invite notif accepting * fix: lint + fmt * feat: impl install to play * feat: impl usage of UpdateToPlayModal * feat: warnings on deleting/disabling shared-instance version content * fix: send instance name * feat: align with backend * feat: shared instances qa * feat: wrong account protection * feat: qa * fix: smartly apply updates * fix: install bug * fix: 401/404 differentiation * fix: fmt+prepr * feat: qa * feat: qa * fix: signing out messes up revoke/deleted checks * feat: qa * fix: fmt + lint * feat: lock content if part of shared instance * fix: lint * [do not merge] feat: rough invite links impl temp (#6666) * fix: wrong cmd * feat: invite page * fix: server-manager DTO mismatch * fix: drop anonymous invite link acceptance * refactor: structured shared-instance unavailable errors * refactor: centralise error presentations * refactor: dedupe shared instance diff detection * fix: logging in reqwests * refactor: move app.vue shared instances into handler * refactor: break up Share.vue * refactor: split up shared instances state outside of instance index * refactor: dedicated shared instances install/update modals + split up page * refactor: centralized managed content * refactor: split up install shared to own runner + shared.rs split up * refactor: dedupe sql for instance metadata enrichmnt * refactor: friends composable + dedupe friends logic across usages * chore: reduced unused code * fix: align with backend * fix: lint * fix: file sha changes * fix: invite links not working due to icon signed * feat: qa * feat: reporting frontend dummy * fix: try use header * remove: file hash field * fix: pin box * feat: malware warning for shared instances * fix: cache rule * feat: config files syncing * feat: disable config sharing * fix: header * fix: use mark ready * fix: dont cause push update for configs * fix: lint * feat: sharing page in settings * feat: move config + change flow * fix: qa * fix: lint prepr * feat: proxy file upload thru shared instances backend * fix: use collapisible * fix: push config * fix: config * feat: swap out sign in modal for new one * fix: report flow * fix: exclude configs.zip from external warnings * fix: nuxi init * fix: config bundle downloading * fix: error notif * fix: polling * fix: qa * fix: lint + prepr * feat: shared instances moderation frontend + hook up report flow * fix: report copy * fix: lint * fix: lint * fix: modrinth ids being undefined * feat: instance quarantining * fix: prepr + fmt * fix: quarantined -> locked terminology * fix: missing endpoint impls + fmt * fix: missing api in build.rs * fix: share tab jittery * fix: fmt *PT bug * fix: invites count as users even if pending * fix: prepr * fix: invite page owner in users list * fix: lint * fix: qa * fix: lint * fix: members stale not clearing * fix: invite use joined_at field * fix: lint * fix: qa --------- Co-authored-by: sychic <47618543+Sychic@users.noreply.github.com>
196 lines
6.3 KiB
Vue
196 lines
6.3 KiB
Vue
<template>
|
|
<div v-if="canUnpublish" class="flex flex-col gap-2.5">
|
|
<span class="text-lg font-semibold text-contrast">{{ formatMessage(messages.title) }}</span>
|
|
<div>
|
|
<ButtonStyled color="orange">
|
|
<button :disabled="busy" @click="unpublishModal?.show()">
|
|
<SpinnerIcon v-if="unpublishing" class="animate-spin" />
|
|
<UnlinkIcon v-else class="size-5" />
|
|
{{ formatMessage(unpublishing ? messages.unpublishingButton : messages.unpublishButton) }}
|
|
</button>
|
|
</ButtonStyled>
|
|
</div>
|
|
<span class="text-primary">{{ formatMessage(messages.unpublishDescription) }}</span>
|
|
</div>
|
|
<div v-if="canUnlink" class="flex flex-col gap-2.5">
|
|
<span class="text-lg font-semibold text-contrast">{{
|
|
formatMessage(messages.linkedTitle)
|
|
}}</span>
|
|
<div>
|
|
<ButtonStyled color="orange">
|
|
<button :disabled="busy" @click="unlinkModal?.show()">
|
|
<SpinnerIcon v-if="unlinking" class="animate-spin" />
|
|
<UnlinkIcon v-else class="size-5" />
|
|
{{ formatMessage(unlinking ? messages.unlinkingButton : messages.unlinkButton) }}
|
|
</button>
|
|
</ButtonStyled>
|
|
</div>
|
|
<span class="text-primary">{{ formatMessage(messages.unlinkDescription) }}</span>
|
|
</div>
|
|
|
|
<NewModal
|
|
ref="unpublishModal"
|
|
:header="formatMessage(messages.unpublishModalHeader)"
|
|
fade="warning"
|
|
max-width="500px"
|
|
>
|
|
<Admonition type="warning" :header="formatMessage(messages.unpublishModalAdmonitionHeader)">{{
|
|
formatMessage(messages.unpublishModalBody)
|
|
}}</Admonition>
|
|
<template #actions
|
|
><div class="flex justify-end gap-2">
|
|
<ButtonStyled type="outlined"
|
|
><button class="!border" @click="unpublishModal?.hide()">
|
|
<XIcon />{{ formatMessage(commonMessages.cancelButton) }}
|
|
</button></ButtonStyled
|
|
><ButtonStyled color="orange"
|
|
><button :disabled="busy" @click="confirmUnpublish">
|
|
<UnlinkIcon />{{ formatMessage(messages.unpublishButton) }}
|
|
</button></ButtonStyled
|
|
>
|
|
</div></template
|
|
>
|
|
</NewModal>
|
|
<NewModal
|
|
ref="unlinkModal"
|
|
:header="formatMessage(messages.unlinkModalHeader)"
|
|
fade="warning"
|
|
max-width="500px"
|
|
:on-hide="() => backupCreator?.cancelBackup()"
|
|
>
|
|
<div class="flex flex-col gap-6">
|
|
<Admonition type="warning" :header="formatMessage(messages.unlinkModalAdmonitionHeader)">{{
|
|
formatMessage(messages.unlinkModalBody)
|
|
}}</Admonition>
|
|
<InlineBackupCreator
|
|
ref="backupCreator"
|
|
backup-name="Before unlinking shared instance"
|
|
@update:buttons-disabled="backupBusy = $event"
|
|
/>
|
|
</div>
|
|
<template #actions
|
|
><div class="flex justify-end gap-2">
|
|
<ButtonStyled type="outlined"
|
|
><button class="!border" @click="unlinkModal?.hide()">
|
|
<XIcon />{{ formatMessage(commonMessages.cancelButton) }}
|
|
</button></ButtonStyled
|
|
><ButtonStyled color="orange"
|
|
><button :disabled="busy || backupBusy" @click="confirmUnlink">
|
|
<UnlinkIcon />{{ formatMessage(messages.unlinkButton) }}
|
|
</button></ButtonStyled
|
|
>
|
|
</div></template
|
|
>
|
|
</NewModal>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { SpinnerIcon, UnlinkIcon, XIcon } from '@modrinth/assets'
|
|
import {
|
|
Admonition,
|
|
ButtonStyled,
|
|
commonMessages,
|
|
defineMessages,
|
|
InlineBackupCreator,
|
|
NewModal,
|
|
useVIntl,
|
|
} from '@modrinth/ui'
|
|
import { ref } from 'vue'
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
canUnpublish?: boolean
|
|
canUnlink?: boolean
|
|
busy: boolean
|
|
unpublishing?: boolean
|
|
unlinking?: boolean
|
|
unpublish?: () => Promise<void>
|
|
unlink?: () => Promise<void>
|
|
}>(),
|
|
{
|
|
canUnpublish: false,
|
|
canUnlink: false,
|
|
unpublishing: false,
|
|
unlinking: false,
|
|
unpublish: undefined,
|
|
unlink: undefined,
|
|
},
|
|
)
|
|
const { formatMessage } = useVIntl()
|
|
const unpublishModal = ref<InstanceType<typeof NewModal>>()
|
|
const unlinkModal = ref<InstanceType<typeof NewModal>>()
|
|
const backupCreator = ref<InstanceType<typeof InlineBackupCreator>>()
|
|
const backupBusy = ref(false)
|
|
|
|
async function confirmUnpublish() {
|
|
unpublishModal.value?.hide()
|
|
await props.unpublish?.()
|
|
}
|
|
async function confirmUnlink() {
|
|
unlinkModal.value?.hide()
|
|
await props.unlink?.()
|
|
}
|
|
|
|
const messages = defineMessages({
|
|
title: {
|
|
id: 'installation-settings.shared-instance.title',
|
|
defaultMessage: 'Unpublish instance',
|
|
},
|
|
linkedTitle: {
|
|
id: 'installation-settings.shared-instance.linked-title',
|
|
defaultMessage: 'Linked shared instance',
|
|
},
|
|
unpublishButton: {
|
|
id: 'installation-settings.shared-instance.unpublish-button',
|
|
defaultMessage: 'Unpublish shared instance',
|
|
},
|
|
unpublishingButton: {
|
|
id: 'installation-settings.shared-instance.unpublishing-button',
|
|
defaultMessage: 'Unpublishing...',
|
|
},
|
|
unpublishDescription: {
|
|
id: 'installation-settings.shared-instance.unpublish-description',
|
|
defaultMessage:
|
|
'Remove this shared instance from Modrinth and stop sending updates to anyone using it. Your local instance will not be affected.',
|
|
},
|
|
unlinkButton: {
|
|
id: 'installation-settings.shared-instance.unlink-button',
|
|
defaultMessage: 'Unlink shared instance',
|
|
},
|
|
unlinkingButton: {
|
|
id: 'installation-settings.shared-instance.unlinking-button',
|
|
defaultMessage: 'Unlinking...',
|
|
},
|
|
unlinkDescription: {
|
|
id: 'installation-settings.shared-instance.unlink-description',
|
|
defaultMessage: 'Disconnect this local instance from future shared updates.',
|
|
},
|
|
unpublishModalHeader: {
|
|
id: 'installation-settings.unpublish-shared-instance.modal.header',
|
|
defaultMessage: 'Unpublish shared instance',
|
|
},
|
|
unpublishModalAdmonitionHeader: {
|
|
id: 'installation-settings.unpublish-shared-instance.modal.admonition-header',
|
|
defaultMessage: 'Unpublishing shared instance',
|
|
},
|
|
unpublishModalBody: {
|
|
id: 'installation-settings.unpublish-shared-instance.modal.admonition-body',
|
|
defaultMessage:
|
|
"This deletes the shared instance from Modrinth's servers. People using it in the Modrinth App will stop receiving updates, but your local instance and its content will stay on this device.",
|
|
},
|
|
unlinkModalHeader: {
|
|
id: 'installation-settings.unlink-shared-instance.modal.header',
|
|
defaultMessage: 'Unlink shared instance',
|
|
},
|
|
unlinkModalAdmonitionHeader: {
|
|
id: 'installation-settings.unlink-shared-instance.modal.admonition-header',
|
|
defaultMessage: 'Unlinking shared instance',
|
|
},
|
|
unlinkModalBody: {
|
|
id: 'installation-settings.unlink-shared-instance.modal.admonition-body',
|
|
defaultMessage:
|
|
'This only affects your local instance. Your installed content will stay on this device, and the shared instance and other people using it will not be affected.',
|
|
},
|
|
})
|
|
</script>
|