feat: handle open Jan on HF GGUF repo (#5173)
* feat: handle open Jan on HF GGUF repo * chore: reset retry attempts
This commit is contained in:
parent
817e3175f3
commit
ecef9d7df6
@ -90,7 +90,7 @@ export default class JanInferenceCortexExtension extends LocalOAIEngine {
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
}
|
||||
: {},
|
||||
retry: 4,
|
||||
retry: 10,
|
||||
})
|
||||
return this.api
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ dirs = "6.0.0"
|
||||
sysinfo = "0.34.2"
|
||||
ash = "0.38.0"
|
||||
nvml-wrapper = "0.10.0"
|
||||
tauri-plugin-deep-link = "2"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
libloading = "0.8.7"
|
||||
@ -59,3 +60,4 @@ libc = "0.2.172"
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||
tauri-plugin-updater = "2"
|
||||
once_cell = "1.18"
|
||||
tauri-plugin-single-instance = { version = "2.0.0", features = ["deep-link"] }
|
||||
|
||||
19
src-tauri/Info.plist
Normal file
19
src-tauri/Info.plist
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>jan.ai.app</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>jan.ai.app</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>jan</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -19,6 +19,7 @@
|
||||
"log:default",
|
||||
"updater:default",
|
||||
"dialog:default",
|
||||
"deep-link:default",
|
||||
"core:webview:allow-create-webview-window",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
|
||||
@ -14,8 +14,16 @@ use reqwest::blocking::Client;
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_os::init())
|
||||
let mut builder = tauri::Builder::default();
|
||||
#[cfg(desktop)]
|
||||
{
|
||||
builder = builder.plugin(tauri_plugin_single_instance::init(|_app, argv, _cwd| {
|
||||
println!("a new app instance was opened with {argv:?} and the deep link event was already triggered");
|
||||
// when defining deep link schemes at runtime, you must also check `argv` here
|
||||
}));
|
||||
}
|
||||
builder.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_deep_link::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_http::init())
|
||||
|
||||
@ -68,7 +68,8 @@
|
||||
"windows": {
|
||||
"installMode": "passive"
|
||||
}
|
||||
}
|
||||
},
|
||||
"deep-link": { "schemes": ["jan"] }
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
"@tanstack/react-router": "^1.116.0",
|
||||
"@tanstack/react-router-devtools": "^1.116.0",
|
||||
"@tauri-apps/api": "^2.5.0",
|
||||
"@tauri-apps/plugin-deep-link": "~2",
|
||||
"@tauri-apps/plugin-dialog": "^2.2.1",
|
||||
"@tauri-apps/plugin-opener": "^2.2.7",
|
||||
"@tauri-apps/plugin-os": "^2.2.1",
|
||||
|
||||
@ -13,6 +13,12 @@ import { getMCPConfig } from '@/services/mcp'
|
||||
import { useAssistant } from '@/hooks/useAssistant'
|
||||
import { getAssistants } from '@/services/assistants'
|
||||
import { migrateData } from '@/utils/migration'
|
||||
import {
|
||||
onOpenUrl,
|
||||
getCurrent as getCurrentDeepLinkUrls,
|
||||
} from '@tauri-apps/plugin-deep-link'
|
||||
import { useNavigate } from '@tanstack/react-router'
|
||||
import { route } from '@/constants/routes'
|
||||
|
||||
export function DataProvider() {
|
||||
const { setProviders } = useModelProvider()
|
||||
@ -21,6 +27,7 @@ export function DataProvider() {
|
||||
const { checkForUpdate } = useAppUpdater()
|
||||
const { setServers } = useMCPServers()
|
||||
const { setAssistants } = useAssistant()
|
||||
const navigate = useNavigate()
|
||||
|
||||
useEffect(() => {
|
||||
fetchModels().then((models) => {
|
||||
@ -39,6 +46,8 @@ export function DataProvider() {
|
||||
console.warn('Failed to load assistants, keeping default:', error)
|
||||
})
|
||||
migrateData()
|
||||
getCurrentDeepLinkUrls().then(handleDeepLink)
|
||||
onOpenUrl(handleDeepLink)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
@ -58,5 +67,27 @@ export function DataProvider() {
|
||||
checkForUpdate()
|
||||
}, [checkForUpdate])
|
||||
|
||||
const handleDeepLink = (urls: string[] | null) => {
|
||||
if (!urls) return
|
||||
console.log('Received deeplink:', urls)
|
||||
const deeplink = urls[0]
|
||||
if (deeplink) {
|
||||
const url = new URL(deeplink)
|
||||
const params = url.pathname.split('/').filter((str) => str.length > 0)
|
||||
|
||||
if (params.length < 3) return undefined
|
||||
// const action = params[0]
|
||||
// const provider = params[1]
|
||||
const resource = params.slice(1).join('/')
|
||||
// return { action, provider, resource }
|
||||
navigate({
|
||||
to: route.hub,
|
||||
search: {
|
||||
repo: resource,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
import { createFileRoute, Link, useNavigate } from '@tanstack/react-router'
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import {
|
||||
createFileRoute,
|
||||
Link,
|
||||
useNavigate,
|
||||
useSearch,
|
||||
} from '@tanstack/react-router'
|
||||
import { route } from '@/constants/routes'
|
||||
import { useModelSources } from '@/hooks/useModelSources'
|
||||
import { cn, fuzzySearch, toGigabytes } from '@/lib/utils'
|
||||
@ -37,10 +43,15 @@ type ModelProps = {
|
||||
}[]
|
||||
}
|
||||
}
|
||||
type SearchParams = {
|
||||
repo: string
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const Route = createFileRoute(route.hub as any)({
|
||||
component: Hub,
|
||||
validateSearch: (search: Record<string, unknown>): SearchParams => ({
|
||||
repo: search.repo as SearchParams['repo'],
|
||||
}),
|
||||
})
|
||||
|
||||
const sortOptions = [
|
||||
@ -50,6 +61,7 @@ const sortOptions = [
|
||||
|
||||
function Hub() {
|
||||
const { sources, fetchSources, loading } = useModelSources()
|
||||
const search = useSearch({ from: route.hub as any })
|
||||
const [searchValue, setSearchValue] = useState('')
|
||||
const [sortSelected, setSortSelected] = useState('newest')
|
||||
const [expandedModels, setExpandedModels] = useState<Record<string, boolean>>(
|
||||
@ -71,6 +83,22 @@ function Hub() {
|
||||
}))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (search.repo) {
|
||||
setSearchValue(search.repo || '')
|
||||
setIsSearching(true)
|
||||
addModelSourceTimeoutRef.current = setTimeout(() => {
|
||||
addModelSource(search.repo)
|
||||
.then(() => {
|
||||
fetchSources()
|
||||
})
|
||||
.finally(() => {
|
||||
setIsSearching(false)
|
||||
})
|
||||
}, 500)
|
||||
}
|
||||
}, [fetchSources, search])
|
||||
|
||||
// Sorting functionality
|
||||
const sortedModels = useMemo(() => {
|
||||
return [...sources].sort((a, b) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user