mirror of
https://github.com/modrinth/code.git
synced 2026-09-04 22:10:15 +00:00
Merge branch 'truman/shared-ui-auth-di' into truman/new-server-card-states
This commit is contained in:
@@ -40,6 +40,7 @@ import {
|
|||||||
OverflowMenu,
|
OverflowMenu,
|
||||||
PopupNotificationPanel,
|
PopupNotificationPanel,
|
||||||
ProgressSpinner,
|
ProgressSpinner,
|
||||||
|
provideAuth,
|
||||||
provideModalBehavior,
|
provideModalBehavior,
|
||||||
provideModrinthClient,
|
provideModrinthClient,
|
||||||
provideNotificationManager,
|
provideNotificationManager,
|
||||||
@@ -57,7 +58,7 @@ import { openUrl } from '@tauri-apps/plugin-opener'
|
|||||||
import { type } from '@tauri-apps/plugin-os'
|
import { type } from '@tauri-apps/plugin-os'
|
||||||
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
||||||
import { $fetch } from 'ofetch'
|
import { $fetch } from 'ofetch'
|
||||||
import { computed, onMounted, onUnmounted, provide, ref, watch } from 'vue'
|
import { computed, onMounted, onUnmounted, provide, reactive, ref, watch, watchEffect } from 'vue'
|
||||||
import { RouterView, useRoute, useRouter } from 'vue-router'
|
import { RouterView, useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
import ModrinthAppLogo from '@/assets/modrinth_app.svg?component'
|
import ModrinthAppLogo from '@/assets/modrinth_app.svg?component'
|
||||||
@@ -454,6 +455,21 @@ const credentials = ref()
|
|||||||
|
|
||||||
const modrinthLoginFlowWaitModal = ref()
|
const modrinthLoginFlowWaitModal = ref()
|
||||||
|
|
||||||
|
const authProvider = reactive({
|
||||||
|
session_token: null,
|
||||||
|
user: null,
|
||||||
|
requestSignIn: async (_redirectPath) => {
|
||||||
|
await signIn()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
authProvider.session_token = credentials.value?.session ?? null
|
||||||
|
authProvider.user = credentials.value?.user ?? null
|
||||||
|
})
|
||||||
|
|
||||||
|
provideAuth(authProvider)
|
||||||
|
|
||||||
async function fetchCredentials() {
|
async function fetchCredentials() {
|
||||||
const creds = await getCreds().catch(handleError)
|
const creds = await getCreds().catch(handleError)
|
||||||
if (creds && creds.user_id) {
|
if (creds && creds.user_id) {
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ pub enum ErrorKind {
|
|||||||
Tracing(#[from] tracing::subscriber::SetGlobalDefaultError),
|
Tracing(#[from] tracing::subscriber::SetGlobalDefaultError),
|
||||||
#[error("Zip error: {0}")]
|
#[error("Zip error: {0}")]
|
||||||
Zip(#[from] async_zip::error::ZipError),
|
Zip(#[from] async_zip::error::ZipError),
|
||||||
|
#[error("Failed to parse an integer: {0}")]
|
||||||
|
ParseIntError(#[from] std::num::ParseIntError),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -141,9 +141,16 @@ pub async fn fetch_neo(
|
|||||||
}).chain(neo_versions.versioning.versions.version.into_iter().map(|loader_version| {
|
}).chain(neo_versions.versioning.versions.version.into_iter().map(|loader_version| {
|
||||||
let mut parts = loader_version.split('.');
|
let mut parts = loader_version.split('.');
|
||||||
|
|
||||||
// NeoForge Forge versions are in this format: 20.2.29-beta, 20.6.119
|
// NeoForge Forge versions are in either of these formats:
|
||||||
// Where the first number is the major MC version, the second is the minor MC version, and the third is the NeoForge version
|
// - 20.2.29-beta, 20.6.119
|
||||||
let major = parts.next().ok_or_else(
|
// - 26.1.0.10-beta, 26.1.0.16
|
||||||
|
//
|
||||||
|
// The first format is the "modern" format for Minecraft versions starting with 1, where the first number is the major MC version,
|
||||||
|
// the second is the minor MC version, and the third is the NeoForge version.
|
||||||
|
//
|
||||||
|
// The second format is the "new-modern" format for Minecraft versions in year-based format, where the first three numbers
|
||||||
|
// are the Minecraft version (year.release.hotfix), and the fourth, the NeoForge release version, with an optional "beta" suffix.
|
||||||
|
let major_or_year = parts.next().ok_or_else(
|
||||||
|| crate::ErrorKind::InvalidInput(format!("Unable to find major game version for NeoForge {loader_version}"))
|
|| crate::ErrorKind::InvalidInput(format!("Unable to find major game version for NeoForge {loader_version}"))
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@@ -151,11 +158,24 @@ pub async fn fetch_neo(
|
|||||||
|| crate::ErrorKind::InvalidInput(format!("Unable to find minor game version for NeoForge {loader_version}"))
|
|| crate::ErrorKind::InvalidInput(format!("Unable to find minor game version for NeoForge {loader_version}"))
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let game_version = if minor == "0" {
|
let major_or_year = major_or_year.parse::<u32>()?;
|
||||||
format!("1.{major}")
|
|
||||||
} else {
|
// Year-based MC versions started in 2026
|
||||||
format!("1.{major}.{minor}")
|
let game_version = match major_or_year {
|
||||||
};
|
26.. => {
|
||||||
|
let hotfix = parts.next().ok_or_else(
|
||||||
|
|| crate::ErrorKind::InvalidInput(format!("Unable to find hotfix version for NeoForge {loader_version}"))
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if hotfix == "0" {
|
||||||
|
format!("{major_or_year}.{minor}")
|
||||||
|
} else {
|
||||||
|
format!("{major_or_year}.{minor}.{hotfix}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
..26 if minor == "0" => format!("1.{major_or_year}"),
|
||||||
|
..26 => format!("1.{major_or_year}.{minor}"),
|
||||||
|
};
|
||||||
|
|
||||||
Ok(ForgeVersion {
|
Ok(ForgeVersion {
|
||||||
format_version: 2,
|
format_version: 2,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { provideNotificationManager } from '@modrinth/ui'
|
import { provideNotificationManager } from '@modrinth/ui'
|
||||||
|
|
||||||
import { FrontendNotificationManager } from './frontend-notifications'
|
import { FrontendNotificationManager } from './frontend-notifications'
|
||||||
|
import { setupAuthProvider } from './setup/auth'
|
||||||
import { setupFilePickerProvider } from './setup/file-picker'
|
import { setupFilePickerProvider } from './setup/file-picker'
|
||||||
import { setupModrinthClientProvider } from './setup/modrinth-client'
|
import { setupModrinthClientProvider } from './setup/modrinth-client'
|
||||||
import { setupPageContextProvider } from './setup/page-context'
|
import { setupPageContextProvider } from './setup/page-context'
|
||||||
@@ -9,6 +10,7 @@ import { setupTagsProvider } from './setup/tags'
|
|||||||
export function setupProviders(auth: Awaited<ReturnType<typeof useAuth>>) {
|
export function setupProviders(auth: Awaited<ReturnType<typeof useAuth>>) {
|
||||||
provideNotificationManager(new FrontendNotificationManager())
|
provideNotificationManager(new FrontendNotificationManager())
|
||||||
|
|
||||||
|
setupAuthProvider(auth)
|
||||||
setupModrinthClientProvider(auth)
|
setupModrinthClientProvider(auth)
|
||||||
setupTagsProvider()
|
setupTagsProvider()
|
||||||
setupFilePickerProvider()
|
setupFilePickerProvider()
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import type { Labrinth } from '@modrinth/api-client'
|
||||||
|
import { type AuthProvider, provideAuth } from '@modrinth/ui'
|
||||||
|
import { reactive, watchEffect } from 'vue'
|
||||||
|
|
||||||
|
export function setupAuthProvider(auth: Awaited<ReturnType<typeof useAuth>>) {
|
||||||
|
const router = useRouter()
|
||||||
|
const authProvider = reactive<AuthProvider>({
|
||||||
|
session_token: null,
|
||||||
|
user: null,
|
||||||
|
requestSignIn: async (redirectPath: string) => {
|
||||||
|
await router.push({
|
||||||
|
path: '/auth/sign-in',
|
||||||
|
query: {
|
||||||
|
redirect: redirectPath,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
authProvider.session_token = auth.value.token || null
|
||||||
|
authProvider.user = (auth.value.user as Labrinth.Users.v2.User | null) ?? null
|
||||||
|
})
|
||||||
|
|
||||||
|
provideAuth(authProvider)
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import type { Labrinth } from '@modrinth/api-client/src/modules/labrinth/types'
|
||||||
|
|
||||||
|
import { createContext } from './create-context'
|
||||||
|
|
||||||
|
export interface AuthProvider {
|
||||||
|
session_token: string | null
|
||||||
|
user: Labrinth.Users.v2.User | null
|
||||||
|
requestSignIn: (redirectPath: string) => void | Promise<void>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const [injectAuth, provideAuth] = createContext<AuthProvider>('root', 'auth')
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './api-client'
|
export * from './api-client'
|
||||||
|
export * from './auth'
|
||||||
export * from './app-backup'
|
export * from './app-backup'
|
||||||
export * from './content-manager'
|
export * from './content-manager'
|
||||||
export { createContext } from './create-context'
|
export { createContext } from './create-context'
|
||||||
|
|||||||
Reference in New Issue
Block a user