chore: change jan default data folder path to app's userData (#3443)

* chore: change jan default data folder path to app's userData

* fix: legacy factory reset does not work properly

* chore: update jan data folder path on UI accordingly

* chore: change jan data folder to Jan/data
This commit is contained in:
Louis 2024-08-23 19:21:24 +07:00 committed by GitHub
parent e98cb78230
commit 925cd04d20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 41 additions and 30 deletions

View File

@ -1,7 +1,7 @@
import { join } from 'path' import { join } from 'path'
import fs from 'fs' import fs from 'fs'
import { appResourcePath, normalizeFilePath, validatePath } from '../../helper/path' import { appResourcePath, normalizeFilePath, validatePath } from '../../helper/path'
import { getJanDataFolderPath, getJanDataFolderPath as getPath } from '../../helper' import { defaultAppConfig, getJanDataFolderPath, getJanDataFolderPath as getPath } from '../../helper'
import { Processor } from './Processor' import { Processor } from './Processor'
import { FileStat } from '../../../types' import { FileStat } from '../../../types'
@ -28,9 +28,10 @@ export class FSExt implements Processor {
return appResourcePath() return appResourcePath()
} }
// Handles the 'getUserHomePath' IPC event. This event is triggered to get the user home path. // Handles the 'getUserHomePath' IPC event. This event is triggered to get the user app data path.
// CAUTION: This would not return OS home path but the app data path.
getUserHomePath() { getUserHomePath() {
return process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME'] return defaultAppConfig().data_folder
} }
// handle fs is directory here // handle fs is directory here

View File

@ -3,27 +3,16 @@ import { join, resolve } from 'path'
import fs from 'fs' import fs from 'fs'
import os from 'os' import os from 'os'
import childProcess from 'child_process' import childProcess from 'child_process'
const configurationFileName = 'settings.json' const configurationFileName = 'settings.json'
// TODO: do no specify app name in framework module
// TODO: do not default the os.homedir
const defaultJanDataFolder = join(os?.homedir() || '', 'jan')
const defaultAppConfig: AppConfiguration = {
data_folder:
process.env.CI === 'e2e'
? process.env.APP_CONFIG_PATH ?? resolve('./test-data')
: defaultJanDataFolder,
quick_ask: false,
}
/** /**
* Getting App Configurations. * Getting App Configurations.
* *
* @returns {AppConfiguration} The app configurations. * @returns {AppConfiguration} The app configurations.
*/ */
export const getAppConfigurations = (): AppConfiguration => { export const getAppConfigurations = (): AppConfiguration => {
if (process.env.CI === 'e2e') return defaultAppConfig const appDefaultConfiguration = defaultAppConfig()
if (process.env.CI === 'e2e') return appDefaultConfiguration
// Retrieve Application Support folder path // Retrieve Application Support folder path
// Fallback to user home directory if not found // Fallback to user home directory if not found
const configurationFile = getConfigurationFilePath() const configurationFile = getConfigurationFilePath()
@ -31,8 +20,8 @@ export const getAppConfigurations = (): AppConfiguration => {
if (!fs.existsSync(configurationFile)) { if (!fs.existsSync(configurationFile)) {
// create default app config if we don't have one // create default app config if we don't have one
console.debug(`App config not found, creating default config at ${configurationFile}`) console.debug(`App config not found, creating default config at ${configurationFile}`)
fs.writeFileSync(configurationFile, JSON.stringify(defaultAppConfig)) fs.writeFileSync(configurationFile, JSON.stringify(appDefaultConfiguration))
return defaultAppConfig return appDefaultConfiguration
} }
try { try {
@ -42,7 +31,7 @@ export const getAppConfigurations = (): AppConfiguration => {
return appConfigurations return appConfigurations
} catch (err) { } catch (err) {
console.error(`Failed to read app config, return default config instead! Err: ${err}`) console.error(`Failed to read app config, return default config instead! Err: ${err}`)
return defaultAppConfig return defaultAppConfig()
} }
} }
@ -159,3 +148,22 @@ export const getEngineConfiguration = async (engineId: string) => {
full_url: fullUrl, full_url: fullUrl,
} }
} }
/**
* Default app configurations
* App Data Folder default to Electron's userData
* %APPDATA% on Windows
* $XDG_CONFIG_HOME or ~/.config on Linux
* ~/Library/Application Support on macOS
*/
export const defaultAppConfig = (): AppConfiguration => {
const { app } = require('electron')
const defaultJanDataFolder = join(app?.getPath('userData') ?? os?.homedir() ?? '', 'data')
return {
data_folder:
process.env.CI === 'e2e'
? (process.env.APP_CONFIG_PATH ?? resolve('./test-data'))
: defaultJanDataFolder,
quick_ask: false,
}
}

View File

@ -38,8 +38,7 @@ export default function RootLayout() {
useEffect(() => { useEffect(() => {
async function getDefaultJanDataFolder() { async function getDefaultJanDataFolder() {
const homePath = await getUserHomePath() const defaultJanDataFolder = await getUserHomePath()
const defaultJanDataFolder = await joinPath([homePath, 'jan'])
setJanDefaultDataFolder(defaultJanDataFolder) setJanDefaultDataFolder(defaultJanDataFolder)
} }

View File

@ -47,8 +47,7 @@ const DataLoader: React.FC<Props> = ({ children }) => {
useEffect(() => { useEffect(() => {
async function getDefaultJanDataFolder() { async function getDefaultJanDataFolder() {
const homePath = await getUserHomePath() const defaultJanDataFolder = await getUserHomePath()
const defaultJanDataFolder = await joinPath([homePath, 'jan'])
setJanDefaultDataFolder(defaultJanDataFolder) setJanDefaultDataFolder(defaultJanDataFolder)
} }

View File

@ -34,7 +34,16 @@ export default function useFactoryReset() {
} }
const janDataFolderPath = appConfiguration!.data_folder const janDataFolderPath = appConfiguration!.data_folder
// 1: Stop running model
setFactoryResetState(FactoryResetState.StoppingModel)
await stopModel()
await new Promise((resolve) => setTimeout(resolve, 4000))
// 2: Delete the old jan data folder
setFactoryResetState(FactoryResetState.DeletingData)
await fs.rm(janDataFolderPath)
// 3: Set the default jan data folder
if (!keepCurrentFolder) { if (!keepCurrentFolder) {
// set the default jan data folder to user's home directory // set the default jan data folder to user's home directory
const configuration: AppConfiguration = { const configuration: AppConfiguration = {
@ -44,17 +53,12 @@ export default function useFactoryReset() {
await window.core?.api?.updateAppConfiguration(configuration) await window.core?.api?.updateAppConfiguration(configuration)
} }
setFactoryResetState(FactoryResetState.StoppingModel) // 4: Clear app local storage
await stopModel()
await new Promise((resolve) => setTimeout(resolve, 4000))
setFactoryResetState(FactoryResetState.DeletingData)
await fs.rm(janDataFolderPath)
setFactoryResetState(FactoryResetState.ClearLocalStorage) setFactoryResetState(FactoryResetState.ClearLocalStorage)
// reset the localStorage // reset the localStorage
localStorage.clear() localStorage.clear()
// 5: Relaunch the app
await window.core?.api?.relaunch() await window.core?.api?.relaunch()
}, },
[defaultJanDataFolder, stopModel, setFactoryResetState] [defaultJanDataFolder, stopModel, setFactoryResetState]