Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
36a09c4
feat: card alignment + fix modals
IMB11 Apr 18, 2026
c1687f5
feat: change admon title in restore alert modal
IMB11 Apr 18, 2026
db3bc4e
fix: lint
IMB11 Apr 18, 2026
f1a32d7
feat: backups queue api into api-client
IMB11 Apr 20, 2026
da85a17
feat: impl backup queue api endpoints into frontend
IMB11 Apr 20, 2026
e2d4b5a
Merge remote-tracking branch 'origin/main' into cal/backups-page-refa…
IMB11 Apr 20, 2026
e998a6a
feat: ack fix
IMB11 Apr 20, 2026
c406884
feat: bulk actions
IMB11 Apr 20, 2026
b404140
feat: bulk delete impl
IMB11 Apr 20, 2026
cd6d896
fix: lint
IMB11 Apr 20, 2026
fe755d0
fix: align error states
IMB11 Apr 20, 2026
c69156a
fix: transition group
IMB11 Apr 20, 2026
46e5fc1
feat: ready for qa
IMB11 Apr 20, 2026
a4d29b5
Merge branch 'main' into cal/backups-page-refactor
IMB11 Apr 20, 2026
25333b1
fix: lint
IMB11 Apr 20, 2026
715371f
Merge branch 'cal/backups-page-refactor' of https://github.com/modrin…
IMB11 Apr 20, 2026
01a096e
feat: qa
IMB11 Apr 22, 2026
8afd087
feat: stacked admonitions component
IMB11 Apr 22, 2026
b2d4a2d
fix: issues with stacking
IMB11 Apr 22, 2026
47687c0
feat: hook up admonition stacking + fix app csp for staging kyros nodes
IMB11 Apr 22, 2026
63d80b8
fix: logs.vue
IMB11 Apr 22, 2026
f7205fd
qa: close stack on admonitions click
IMB11 Apr 23, 2026
e0091b0
fix: all problems with stacked admonitions
IMB11 Apr 23, 2026
4818444
qa: admonition cleanup and copy overhaul draft
IMB11 Apr 23, 2026
cfff35c
fix: qa issues padding
IMB11 Apr 23, 2026
1f57ed3
fix: padding bug
IMB11 Apr 23, 2026
04a12fa
feat: qa
IMB11 Apr 24, 2026
592066e
fix: intercom in app csp bug
IMB11 Apr 24, 2026
9f967c4
fix: positioning intercom
IMB11 Apr 24, 2026
35ee7cb
feat: loading overlay on top of console + admon consistency changes
IMB11 Apr 24, 2026
070a4d2
feat: scroll indicator fade in backup delete modal + admon timestamp fix
IMB11 Apr 24, 2026
d7fcd70
feat: move action bar behind modal
IMB11 Apr 24, 2026
d2da284
fix: lint + i18n
IMB11 Apr 24, 2026
e83abf6
fix: server ping spam on filter (cache but clear on unmount)
IMB11 Apr 24, 2026
02133c9
Merge remote-tracking branch 'origin/main' into cal/backups-page-refa…
IMB11 Apr 24, 2026
bf185af
fix: 1 admon fade in flicker issue
IMB11 Apr 24, 2026
368fcc0
chore: temp staging undo
IMB11 Apr 24, 2026
e4e4d42
qa: changes
IMB11 Apr 25, 2026
1171afb
Merge remote-tracking branch 'origin/main' into cal/backups-page-refa…
IMB11 Apr 27, 2026
89f8107
fix: lint
IMB11 Apr 27, 2026
7e098d8
chore: revert staging to use staging
IMB11 Apr 27, 2026
ba5dda4
fix: scoping
IMB11 Apr 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
1 change: 1 addition & 0 deletions AGENTS.md
1 change: 1 addition & 0 deletions apps/app-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"test": "vue-tsc --noEmit"
},
"dependencies": {
"@intercom/messenger-js-sdk": "^0.0.14",
"@modrinth/api-client": "workspace:^",
"@modrinth/assets": "workspace:*",
"@modrinth/ui": "workspace:*",
Expand Down
98 changes: 98 additions & 0 deletions apps/app-frontend/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script setup>
import { Intercom, shutdown as shutdownIntercom } from '@intercom/messenger-js-sdk'
import {
AuthFeature,
NodeAuthFeature,
Expand Down Expand Up @@ -238,6 +239,7 @@ onMounted(async () => {
onUnmounted(async () => {
document.querySelector('body').removeEventListener('click', handleClick)
document.querySelector('body').removeEventListener('auxclick', handleAuxClick)
shutdownHostingIntercom()

await unlistenUpdateDownload?.()
})
Expand Down Expand Up @@ -652,6 +654,102 @@ const sidebarVisible = computed(() => sidebarToggled.value || forceSidebar.value
const showAd = computed(
() => sidebarVisible.value && !hasPlus.value && credentials.value !== undefined,
)
const hostingRouteActive = computed(() => route.path.startsWith('/hosting'))
const INTERCOM_DEFAULT_PADDING = 20
const INTERCOM_APP_SIDEBAR_WIDTH = 300

let intercomBooting = false
let intercomBooted = false

async function fetchIntercomToken() {
const creds = await getCreds()
if (!creds?.session) {
throw new Error('Not authenticated')
}

const params = new URLSearchParams()
if (route.path.startsWith('/hosting/manage/') && typeof route.params.id === 'string') {
params.set('server_id', route.params.id)
}
const query = params.size > 0 ? `?${params.toString()}` : ''

const response = await tauriFetch(`${config.siteUrl}/api/intercom/messenger-jwt${query}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${creds.session}`,
},
})
if (!response.ok) {
throw new Error(`Failed to fetch Intercom token: ${response.status}`)
}
return await response.json()
}

async function bootIntercom() {
if (
intercomBooting ||
intercomBooted ||
!hostingRouteActive.value ||
!credentials.value?.session
) {
return
}

intercomBooting = true
console.debug('[APP][INTERCOM] initializing secure support chat')
try {
const { token } = await fetchIntercomToken()
Intercom({
app_id: 'ykeritl9',
intercom_user_jwt: token,
session_duration: 1000 * 60 * 60 * 24,
alignment: 'right',
horizontal_padding: sidebarVisible.value
? INTERCOM_APP_SIDEBAR_WIDTH + INTERCOM_DEFAULT_PADDING
: INTERCOM_DEFAULT_PADDING,
vertical_padding: INTERCOM_DEFAULT_PADDING,
})
intercomBooted = true
} catch (error) {
console.warn('[APP][INTERCOM] failed to initialize secure support chat', error)
} finally {
intercomBooting = false
}
}

function shutdownHostingIntercom() {
if (!intercomBooted && !intercomBooting) return
shutdownIntercom()
intercomBooting = false
intercomBooted = false
}

watch(
sidebarVisible,
(visible) => {
if (intercomBooted) {
window.Intercom?.('update', {
horizontal_padding: visible
? INTERCOM_APP_SIDEBAR_WIDTH + INTERCOM_DEFAULT_PADDING
: INTERCOM_DEFAULT_PADDING,
vertical_padding: INTERCOM_DEFAULT_PADDING,
})
}
},
{ immediate: true },
)

watch(
[hostingRouteActive, credentials],
([active]) => {
if (active) {
void bootIntercom()
} else {
shutdownHostingIntercom()
}
},
{ immediate: true },
)

watch(showAd, () => {
if (!showAd.value) {
Expand Down
7 changes: 0 additions & 7 deletions apps/app-frontend/src/assets/stylesheets/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,6 @@ img {
}
}

button,
input[type='button'] {
cursor: pointer;
border: none;
outline: 2px solid transparent;
}

@import '@modrinth/assets/omorphia.scss';

input {
Expand Down
4 changes: 2 additions & 2 deletions apps/app-frontend/src/locales/en-US/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
"message": "Discover servers"
},
"app.browse.hide-added-servers": {
"message": "Hide added servers"
"message": "Hide already added servers"
},
"app.browse.hide-installed-content": {
"message": "Hide installed content"
"message": "Hide already installed content"
},
"app.browse.install-content-to-instance": {
"message": "Install content to instance"
Expand Down
Loading
Loading