diff --git a/.github/workflows/template-build-macos-arm64.yml b/.github/workflows/template-build-macos-arm64.yml index 54355d55c..2ef40b7c0 100644 --- a/.github/workflows/template-build-macos-arm64.yml +++ b/.github/workflows/template-build-macos-arm64.yml @@ -78,6 +78,10 @@ jobs: jq '.build.publish = [{"provider": "generic", "url": "${{ secrets.CLOUDFLARE_R2_PUBLIC_URL }}", "channel": "latest"}, {"provider": "s3", "bucket": "${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }}", "region": "auto", "endpoint": "https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com", "path": "${{ inputs.cloudflare_r2_path }}", "channel": "latest"}]' electron/package.json > /tmp/package.json mv /tmp/package.json electron/package.json + + jq --arg teamid "${{ secrets.APPLE_TEAM_ID }}" '.build.mac.notarize.teamId = $teamid' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + cat electron/package.json - name: Update app version base on tag @@ -91,6 +95,9 @@ jobs: mv /tmp/package.json electron/package.json jq --arg version "${VERSION_TAG#v}" '.version = $version' web/package.json > /tmp/package.json mv /tmp/package.json web/package.json + jq --arg teamid "${{ secrets.APPLE_TEAM_ID }}" '.build.mac.notarize.teamId = $teamid' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + cat electron/package.json env: VERSION_TAG: ${{ inputs.new_version }} diff --git a/.github/workflows/template-build-macos-x64.yml b/.github/workflows/template-build-macos-x64.yml index e313c2947..12aad37bd 100644 --- a/.github/workflows/template-build-macos-x64.yml +++ b/.github/workflows/template-build-macos-x64.yml @@ -72,6 +72,10 @@ jobs: jq '.build.publish = [{"provider": "generic", "url": "${{ secrets.CLOUDFLARE_R2_PUBLIC_URL }}", "channel": "latest"}, {"provider": "s3", "bucket": "${{ secrets.CLOUDFLARE_R2_BUCKET_NAME }}", "region": "auto", "endpoint": "https://${{ secrets.CLOUDFLARE_ACCOUNT_ID }}.r2.cloudflarestorage.com", "path": "${{ inputs.cloudflare_r2_path }}", "channel": "latest"}]' electron/package.json > /tmp/package.json mv /tmp/package.json electron/package.json + + jq --arg teamid "${{ secrets.APPLE_TEAM_ID }}" '.build.mac.notarize.teamId = $teamid' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + cat electron/package.json - name: Update app version base on tag @@ -85,6 +89,9 @@ jobs: mv /tmp/package.json electron/package.json jq --arg version "${VERSION_TAG#v}" '.version = $version' web/package.json > /tmp/package.json mv /tmp/package.json web/package.json + jq --arg teamid "${{ secrets.APPLE_TEAM_ID }}" '.build.mac.notarize.teamId = $teamid' electron/package.json > /tmp/package.json + mv /tmp/package.json electron/package.json + cat electron/package.json env: VERSION_TAG: ${{ inputs.new_version }} diff --git a/README.md b/README.md index 748470924..8a4c03098 100644 --- a/README.md +++ b/README.md @@ -76,31 +76,31 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute Experimental (Nightly Build) - + jan.exe - + Intel - + M1/M2 - + jan.deb - + jan.AppImage diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index cd6078327..79d675c7a 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -123,7 +123,7 @@ const config = { docs: { routeBasePath: "/", sidebarPath: require.resolve("./sidebars.js"), - editUrl: "https://github.com/janhq/jan/tree/main/docs", + editUrl: "https://github.com/janhq/jan/tree/dev/docs", showLastUpdateAuthor: true, showLastUpdateTime: true, }, diff --git a/electron/handlers/update.ts b/electron/handlers/update.ts index 0d8cc4cc0..c8e28e580 100644 --- a/electron/handlers/update.ts +++ b/electron/handlers/update.ts @@ -3,6 +3,8 @@ import { WindowManager } from './../managers/window' import { autoUpdater } from 'electron-updater' import { AppEvent } from '@janhq/core' +export let waitingToInstallVersion: string | undefined = undefined + export function handleAppUpdates() { /* Should not check for update during development */ if (!app.isPackaged) { @@ -29,6 +31,7 @@ export function handleAppUpdates() { buttons: ['Restart', 'Later'], }) if (action.response === 0) { + waitingToInstallVersion = _info?.version autoUpdater.quitAndInstall() } }) @@ -37,7 +40,7 @@ export function handleAppUpdates() { autoUpdater.on('error', (info: any) => { WindowManager.instance.currentWindow?.webContents.send( AppEvent.onAppUpdateDownloadError, - info + { failedToInstallVersion: waitingToInstallVersion, info } ) }) diff --git a/web/containers/Layout/BottomBar/UpdateFailedModal/index.tsx b/web/containers/Layout/BottomBar/UpdateFailedModal/index.tsx new file mode 100644 index 000000000..f82fc0ee2 --- /dev/null +++ b/web/containers/Layout/BottomBar/UpdateFailedModal/index.tsx @@ -0,0 +1,69 @@ +import React from 'react' + +import { + Modal, + ModalPortal, + ModalContent, + ModalHeader, + ModalTitle, + ModalFooter, + ModalClose, + Button, +} from '@janhq/uikit' +import { Share2Icon } from '@radix-ui/react-icons' +import { useAtom } from 'jotai' + +import { updateVersionError } from '@/containers/Providers/Jotai' + +const UpdatedFailedModal = () => { + const [error, setError] = useAtom(updateVersionError) + + return ( + setError(undefined)}> + + + + Unable to Install Update + +

+ An error occurred while installing Jan{' '} + {error}. We + appreciate your help with{' '} + + manual downloading and installation. + +

+ +
+ setError(undefined)}> + + + { + window.open('https://github.com/janhq/jan#download', '_blank') + setError(undefined) + }} + > + + +
+
+
+
+ ) +} + +export default UpdatedFailedModal diff --git a/web/containers/Layout/BottomBar/index.tsx b/web/containers/Layout/BottomBar/index.tsx index 66c089744..2373ac3d4 100644 --- a/web/containers/Layout/BottomBar/index.tsx +++ b/web/containers/Layout/BottomBar/index.tsx @@ -17,6 +17,7 @@ import { appDownloadProgress } from '@/containers/Providers/Jotai' import ImportingModelState from './ImportingModelState' import SystemMonitor from './SystemMonitor' +import UpdatedFailedModal from './UpdateFailedModal' const menuLinks = [ { @@ -44,6 +45,7 @@ const BottomBar = () => { +
diff --git a/web/containers/Providers/AppUpdateListener.tsx b/web/containers/Providers/AppUpdateListener.tsx index dceb4df13..542886ee5 100644 --- a/web/containers/Providers/AppUpdateListener.tsx +++ b/web/containers/Providers/AppUpdateListener.tsx @@ -3,10 +3,11 @@ import { Fragment, PropsWithChildren, useEffect } from 'react' import { useSetAtom } from 'jotai' -import { appDownloadProgress } from './Jotai' +import { appDownloadProgress, updateVersionError } from './Jotai' const AppUpdateListener = ({ children }: PropsWithChildren) => { const setProgress = useSetAtom(appDownloadProgress) + const setUpdateVersionError = useSetAtom(updateVersionError) useEffect(() => { if (window && window.electronAPI) { @@ -18,9 +19,13 @@ const AppUpdateListener = ({ children }: PropsWithChildren) => { ) window.electronAPI.onAppUpdateDownloadError( - (_event: string, callback: any) => { - console.error('Download error', callback) + (_event: string, error: any) => { + console.error('Download error: ', error) setProgress(-1) + + // Can not install update + // Prompt user to download the update manually + setUpdateVersionError(error.failedToInstallVersion) } ) diff --git a/web/containers/Providers/Jotai.tsx b/web/containers/Providers/Jotai.tsx index 5907ac746..c43786c89 100644 --- a/web/containers/Providers/Jotai.tsx +++ b/web/containers/Providers/Jotai.tsx @@ -12,6 +12,7 @@ export const editPromptAtom = atom('') export const currentPromptAtom = atom('') export const fileUploadAtom = atom([]) export const appDownloadProgress = atom(-1) +export const updateVersionError = atom(undefined) export const searchAtom = atom('') export default function JotaiWrapper({ children }: Props) { diff --git a/web/screens/ExploreModels/index.tsx b/web/screens/ExploreModels/index.tsx index 1ad0b00ae..484e62b0e 100644 --- a/web/screens/ExploreModels/index.tsx +++ b/web/screens/ExploreModels/index.tsx @@ -20,7 +20,6 @@ import { setImportModelStageAtom } from '@/hooks/useImportModel' import ExploreModelList from './ExploreModelList' import { HuggingFaceModal } from './HuggingFaceModal' -import { experimentalFeatureEnabledAtom } from '@/helpers/atoms/AppConfig.atom' import { configuredModelsAtom, downloadedModelsAtom, @@ -37,8 +36,6 @@ const ExploreModelsScreen = () => { const [showHuggingFaceModal, setShowHuggingFaceModal] = useState(false) const setImportModelStage = useSetAtom(setImportModelStageAtom) - const experimentalFeature = useAtomValue(experimentalFeatureEnabledAtom) - const filteredModels = configuredModels.filter((x) => { if (sortSelected === 'Downloaded') { return ( @@ -59,10 +56,6 @@ const ExploreModelsScreen = () => { setImportModelStage('SELECTING_MODEL') }, [setImportModelStage]) - const onHuggingFaceConverterClick = () => { - setShowHuggingFaceModal(true) - } - return (
{ Import Model
- {experimentalFeature && ( + {/* {experimentalFeature && (

{ Convert from Hugging Face

- )} + )} */}