Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3d81ab0
pnpm prepr
tdgao Aug 19, 2026
ed59417
feat(instance-sync): screenshots sync
IMB11 Aug 19, 2026
d89f70e
fix: prepr + fmt
IMB11 Aug 19, 2026
cbe2e61
fix: qa
IMB11 Aug 24, 2026
fedf33c
feat: screenshit editor
IMB11 Aug 24, 2026
e38daf8
feat: screenshot* editor qa
IMB11 Aug 24, 2026
0522b36
fix: qa
IMB11 Aug 25, 2026
f1ea054
fix: lint
IMB11 Aug 25, 2026
d576004
fix: aecsocket rev
IMB11 Aug 25, 2026
c44dc1c
qa: a11y tab navigation focus is cut off
IMB11 Aug 25, 2026
6b279fe
qa: Change “Edited” badge to be bg-highlight-green
IMB11 Aug 25, 2026
6f8d673
qa: friends list input style wrong
IMB11 Aug 25, 2026
35a858a
qa: toolbar width + labels
IMB11 Aug 25, 2026
c728694
qa: multiselect changes
IMB11 Aug 25, 2026
2f9866c
qa: anim changes
IMB11 Aug 25, 2026
4221b68
qa: card hover colors
IMB11 Aug 25, 2026
6fbb5f1
qa: copy feedback
IMB11 Aug 25, 2026
8129b88
qa: hide date
IMB11 Aug 25, 2026
f1a4708
qa: instance icon in overflow/contextmenu
IMB11 Aug 25, 2026
5ad51cc
qa: spacing
IMB11 Aug 25, 2026
77cf8c1
qa: group empty state text
IMB11 Aug 25, 2026
ade5e67
qa: drag preview badge
IMB11 Aug 25, 2026
d164bac
qa: group deletion skip warning if no screenshots
IMB11 Aug 25, 2026
09d276b
qa: redesign editor
IMB11 Aug 25, 2026
10ebfbf
qa: remove screenshot parent/edited badge stuff
IMB11 Aug 26, 2026
f2a470d
qa: control font size consistency
IMB11 Aug 26, 2026
a996fc4
qa: viewer copy control
IMB11 Aug 26, 2026
bf68329
qa: editor fixes
IMB11 Aug 26, 2026
bd4daa5
qa: redirect on disable screenshot sync
IMB11 Aug 26, 2026
c84fc00
qa: margin police
IMB11 Aug 26, 2026
80b5f33
fix: crop
IMB11 Aug 26, 2026
0d1eceb
fix: qa
IMB11 Aug 27, 2026
4c8ec2c
feat: initial start on basic instance file syncing (#7220)
IMB11 Aug 27, 2026
b5a1c07
qa: final
IMB11 Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/app-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@tauri-apps/plugin-window-state": "^2.2.2",
"@types/three": "^0.172.0",
"@vueuse/core": "^11.1.0",
"ace-builds": "^1.43.5",
"dayjs": "^1.11.10",
"floating-vue": "^5.2.2",
"fuse.js": "^6.6.2",
Expand All @@ -45,6 +46,7 @@
"vue-i18n": "^10.0.0",
"vue-router": "^4.6.0",
"vue-virtual-scroller": "v2.0.0-beta.8",
"vue3-ace-editor": "^2.2.4",
"vuedraggable": "^4.1.0"
},
"devDependencies": {
Expand Down
49 changes: 47 additions & 2 deletions apps/app-frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ChevronLeftIcon,
ChevronRightIcon,
CompassIcon,
ImagesIcon,
LogInIcon,
LogOutIcon,
NewspaperIcon,
Expand Down Expand Up @@ -64,6 +65,7 @@ import { renderString } from '@modrinth/utils'
import { useQuery, useQueryClient } from '@tanstack/vue-query'
import { getVersion } from '@tauri-apps/api/app'
import { convertFileSrc, invoke } from '@tauri-apps/api/core'
import { listen } from '@tauri-apps/api/event'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { fetch as tauriFetch } from '@tauri-apps/plugin-http'
import { openUrl } from '@tauri-apps/plugin-opener'
Expand Down Expand Up @@ -118,7 +120,12 @@ import { debugAnalytics, initAnalytics, trackEvent } from '@/helpers/analytics'
import { check_reachable } from '@/helpers/auth.js'
import { get_user, get_user_many, get_version } from '@/helpers/cache.js'
import { install_create_modpack_instance, install_get_modpack_preview } from '@/helpers/install'
import { can_current_user_use_shared_instances, get as getInstance, run } from '@/helpers/instance'
import {
can_current_user_use_shared_instances,
get as getInstance,
get_global_synced_options,
run,
} from '@/helpers/instance'
import {
get as getCreds,
getAll as getAllCreds,
Expand Down Expand Up @@ -173,7 +180,10 @@ import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
import { get_available_capes, get_available_skins } from './helpers/skins'
import { AppNotificationManager } from './providers/app-notifications'
import { AppPopupNotificationManager } from './providers/app-popup-notifications'
import { appSettingsModalOpenProfileKey } from './providers/app-settings-modal'
import {
appSettingsModalOpenProfileKey,
appSettingsModalOpenSyncedOptionsKey,
} from './providers/app-settings-modal'

const appSettings = useAppSettings()
const appTheme = useTheme()
Expand Down Expand Up @@ -438,6 +448,11 @@ const os = ref('')
const isDevEnvironment = ref(false)

const stateInitialized = ref(false)
const globalSyncedOptionsQuery = useQuery({
queryKey: ['global-synced-options'],
queryFn: get_global_synced_options,
enabled: computed(() => stateInitialized.value),
})

const criticalErrorMessage = ref()

Expand Down Expand Up @@ -469,7 +484,24 @@ const authUnreachable = computed(() => {
return false
})

let unlistenEditMenu

function handleEditMenuAction(action) {
const event = new CustomEvent(`edit-menu:${action}`, { cancelable: true })
if (document.dispatchEvent(event)) document.execCommand(action)
}

onMounted(async () => {
try {
const listeners = await Promise.all([
listen('edit-menu://undo', () => handleEditMenuAction('undo')),
listen('edit-menu://redo', () => handleEditMenuAction('redo')),
])
unlistenEditMenu = () => listeners.forEach((unlisten) => unlisten())
} catch (error) {
handleError(error)
}

await useCheckDisableMouseover()
try {
handleAdsConsentRequired(await should_show_ads_consent_popup())
Expand All @@ -490,6 +522,7 @@ onUnmounted(async () => {
document.querySelector('body').removeEventListener('auxclick', handleAuxClick)
document.querySelector('body').removeEventListener('contextmenu', handleContextMenu)
document.removeEventListener('fullscreenchange', handleFullscreenChange)
unlistenEditMenu?.()
clearDelayedUpdatePopup()

if (fullscreenAdsWindowHold) {
Expand Down Expand Up @@ -557,6 +590,10 @@ const messages = defineMessages({
id: 'app.nav.modrinth-hosting',
defaultMessage: 'Modrinth Hosting',
},
screenshots: {
id: 'app.nav.screenshots',
defaultMessage: 'Screenshots',
},
createNewInstance: {
id: 'app.nav.create-new-instance',
defaultMessage: 'Create new instance',
Expand Down Expand Up @@ -999,6 +1036,7 @@ const updateToPlayModal = ref()
const modrinthLoginModal = ref()
const appSettingsModal = ref()
provide(appSettingsModalOpenProfileKey, () => appSettingsModal.value?.showProfile())
provide(appSettingsModalOpenSyncedOptionsKey, () => appSettingsModal.value?.showSyncedOptions())

watch(incompatibilityWarningModal, (modal) => {
if (modal) {
Expand Down Expand Up @@ -2025,6 +2063,13 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
<NavButton v-tooltip.right="formatMessage(appMessages.skinSelectorLabel)" to="/skins">
<ShirtIcon />
</NavButton>
<NavButton
v-if="globalSyncedOptionsQuery.data.value?.screenshots"
v-tooltip.right="formatMessage(messages.screenshots)"
to="/screenshots"
>
<ImagesIcon />
</NavButton>
<NavButton
v-tooltip.right="formatMessage(messages.modrinthHosting)"
to="/hosting/manage"
Expand Down
5 changes: 3 additions & 2 deletions apps/app-frontend/src/components/ui/friends/FriendsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,11 @@ const messages = defineMessages({
v-model="search"
:icon="SearchIcon"
type="text"
appearance="transparent"
:placeholder="formatMessage(messages.searchFriends)"
clearable
input-class="!bg-transparent !border !border-solid !border-button-bg !text-primary !placeholder:text-primary"
wrapper-class="flex-1 [&>svg]:!text-primary [&>svg]:!opacity-100"
input-class="!text-primary !placeholder:text-primary"
wrapper-class="flex-1 !border-button-bg [&>span:first-child]:!text-primary [&>span:first-child]:!opacity-100"
@keyup.esc="search = ''"
/>
</template>
Expand Down
24 changes: 17 additions & 7 deletions apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script setup lang="ts">
import {
CoffeeIcon,
GameIcon,
GaugeIcon,
HeartHandshakeIcon,
LanguagesIcon,
ModrinthIcon,
PaintbrushIcon,
RefreshCwIcon,
Settings2Icon,
ShieldIcon,
ToggleRightIcon,
Expand All @@ -33,7 +33,7 @@ import AppearanceSettings from '@/components/ui/settings/display/AppearanceSetti
import BehaviorSettings from '@/components/ui/settings/display/BehaviorSettings.vue'
import FeatureFlagSettings from '@/components/ui/settings/display/FeatureFlagSettings.vue'
import LanguageSettings from '@/components/ui/settings/display/LanguageSettings.vue'
import DefaultInstanceSettings from '@/components/ui/settings/instances/DefaultInstanceSettings.vue'
import InstancesSyncedSettings from '@/components/ui/settings/instances/InstancesSyncedSettings.vue'
import JavaSettings from '@/components/ui/settings/instances/JavaSettings.vue'
import ResourceManagementSettings from '@/components/ui/settings/instances/ResourceManagementSettings.vue'
import { useAppSettings } from '@/composables/use-app-settings.ts'
Expand Down Expand Up @@ -130,12 +130,12 @@ const tabs = [
},
{
name: defineMessage({
id: 'app.settings.tabs.default-instance-options',
defaultMessage: 'Default game options',
id: 'app.settings.tabs.synced-options',
defaultMessage: 'Synced options',
}),
category: tabCategories.instances,
icon: GameIcon,
content: DefaultInstanceSettings,
icon: RefreshCwIcon,
content: InstancesSyncedSettings,
},
{
name: defineMessage({
Expand Down Expand Up @@ -232,7 +232,17 @@ function showFeatureFlags(): void {
modal.value?.show()
}

defineExpose({ show, showProfile, showFeatureFlags })
function showSyncedOptions(): void {
const syncedOptionsTabIndex = availableTabs.value.findIndex(
(tab) => tab.content === InstancesSyncedSettings,
)
if (syncedOptionsTabIndex >= 0) {
modal.value?.setTab(syncedOptionsTabIndex)
}
modal.value?.show()
}

defineExpose({ show, showProfile, showFeatureFlags, showSyncedOptions })

const { progress, version: downloadingVersion } = injectAppUpdateDownloadProgress()

Expand Down
Loading
Loading