Skip to content

Commit

Permalink
chore: Release v0.3.3-beta.0 (#2654)
Browse files Browse the repository at this point in the history
  • Loading branch information
DIYgod authored Jan 25, 2025
2 parents 6b029ed + 686efe7 commit 452f7fc
Show file tree
Hide file tree
Showing 328 changed files with 6,337 additions and 2,677 deletions.
66 changes: 65 additions & 1 deletion CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions apps/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"electron-context-menu": "4.0.4",
"electron-log": "5.2.4",
"electron-squirrel-startup": "1.0.1",
"electron-store": "^10.0.0",
"electron-updater": "^6.3.9",
"es-toolkit": "1.29.0",
"fast-folder-size": "2.3.0",
Expand All @@ -53,6 +54,7 @@
"vscode-languagedetection": "npm:@vscode/vscode-languagedetection@^1.0.22"
},
"devDependencies": {
"@follow/types": "workspace:*",
"@types/js-yaml": "4.0.9",
"@types/node": "^22.10.1",
"electron": "33.2.0",
Expand Down
4 changes: 2 additions & 2 deletions apps/main/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const detectingWindows11 = () => {
if (!isWindows) return false

const release = os.release()
const majorVersion = Number.parseInt(release.split(".")[0])
const buildNumber = Number.parseInt(release.split(".")[2])
const majorVersion = Number.parseInt(release.split(".")[0]!)
const buildNumber = Number.parseInt(release.split(".")[2]!)

return majorVersion === 10 && buildNumber >= 22000
}
Expand Down
4 changes: 2 additions & 2 deletions apps/main/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const detectingWindows11 = () => {
if (!isWindows) return false

const release = os.release()
const majorVersion = Number.parseInt(release.split(".")[0])
const buildNumber = Number.parseInt(release.split(".")[2])
const majorVersion = Number.parseInt(release.split(".")[0]!)
const buildNumber = Number.parseInt(release.split(".")[2]!)

return majorVersion === 10 && buildNumber >= 22000
}
Expand Down
5 changes: 2 additions & 3 deletions apps/main/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { env } from "@follow/shared/env"
import { imageRefererMatches, selfRefererMatches } from "@follow/shared/image"
import { parse } from "cookie-es"
import { app, BrowserWindow, session } from "electron"
import type { Cookie } from "electron/main"
import squirrelStartup from "electron-squirrel-startup"

import { DEVICE_ID } from "./constants/system"
Expand Down Expand Up @@ -77,7 +76,7 @@ function bootstrap() {
mainWindow = createMainWindow()

// restore cookies
const cookies = store.get("cookies") as Cookie[]
const cookies = store.get("cookies")
if (cookies) {
Promise.all(
cookies.map((cookie) => {
Expand Down Expand Up @@ -109,7 +108,7 @@ function bootstrap() {
userAgent = userAgent.replace(/\s?Electron\/[\d.]+/, "")
userAgent = userAgent.replace(/\s?Follow\/[\d.a-zA-Z-]+/, "")
}
details.requestHeaders["User-Agent"] = userAgent
details.requestHeaders["User-Agent"] = userAgent!

// set referer and origin
if (selfRefererMatches.some((item) => details.url.startsWith(item))) {
Expand Down
6 changes: 3 additions & 3 deletions apps/main/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { initializeSentry } from "./sentry"
import { router } from "./tipc"
import { createMainWindow, getMainWindow } from "./window"

if (process.argv.length === 3 && process.argv[2].startsWith("follow-dev:")) {
if (process.argv.length === 3 && process.argv[2]!.startsWith("follow-dev:")) {
process.env.NODE_ENV = "development"
}
const isDev = process.env.NODE_ENV === "development"
Expand All @@ -36,7 +36,7 @@ export const initializeAppStage1 = () => {
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient(APP_PROTOCOL, process.execPath, [
path.resolve(process.argv[1]),
path.resolve(process.argv[1]!),
])
}
} else {
Expand Down Expand Up @@ -150,7 +150,7 @@ const registerPushNotifications = async () => {
debug: true,
firebase: JSON.parse(env.VITE_FIREBASE_CONFIG),
persistentIds: persistentIds || [],
credentials: credentials || null,
credentials: credentials || undefined,
bundleId: "is.follow",
chromeId: "is.follow",
})
Expand Down
4 changes: 2 additions & 2 deletions apps/main/src/lib/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const setProxyConfig = (inputProxy: string) => {
}

export const getProxyConfig = () => {
const proxyConfig = store.get("proxy") as string | undefined
const proxyConfig = store.get("proxy")
if (!proxyConfig) {
return
}
Expand All @@ -40,7 +40,7 @@ const normalizeProxyUri = (userProxy: string) => {
return
}
// Only use the first proxy if there are multiple urls
const firstInput = userProxy.split(",")[0]
const firstInput = userProxy.split(",")[0]!

try {
const proxyUrl = new URL(firstInput)
Expand Down
54 changes: 21 additions & 33 deletions apps/main/src/lib/store.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,27 @@
import { resolve } from "node:path"
import type { Credentials } from "@eneris/push-receiver/dist/types"
import type { Cookie } from "electron"
import Store from "electron-store"

import { app } from "electron"
import { JSONFileSyncPreset } from "lowdb/node"

let db: {
data: Record<string, unknown>
write: () => void
read: () => void
}

const createOrGetDb = () => {
if (!db) {
db = JSONFileSyncPreset(resolve(app.getPath("userData"), "db.json"), {}) as typeof db
}
return db
// @keep-sorted
type StoreData = {
"notifications-credentials"?: Credentials | null
"notifications-persistent-ids"?: string[] | null
appearance?: "light" | "dark" | "system" | null
betterAuthSessionCookie?: string | null
cacheSizeLimit?: number | null
cookies?: Cookie[] | null
minimizeToTray?: boolean | null
proxy?: string | null
user?: string | null
windowState?: {
height: number
width: number
x: number
y: number
} | null
}
export const store = new Store<StoreData>({ name: "db" })

export enum StoreKey {
CacheSizeLimit = "cacheSizeLimit",
}

export const store = {
get: (key: string) => {
const db = createOrGetDb()

return db.data[key] as any
},
set: (key: string, value: any) => {
const db = createOrGetDb()
db.data[key] = value
db.write()
},
delete: (key: string) => {
const db = createOrGetDb()
delete db.data[key]
db.write()
},
}
2 changes: 1 addition & 1 deletion apps/main/src/lib/tray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const destroyAppTray = () => {

const DEFAULT_MINIMIZE_TO_TRAY = isMacOS ? false : true

export const getTrayConfig = (): boolean => store.get("minimizeToTray") ?? DEFAULT_MINIMIZE_TO_TRAY
export const getTrayConfig = () => store.get("minimizeToTray") ?? DEFAULT_MINIMIZE_TO_TRAY

export const setTrayConfig = (input: boolean) => {
store.set("minimizeToTray", input)
Expand Down
2 changes: 1 addition & 1 deletion apps/main/src/lib/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { store } from "./store"

const BetterAuthKey = "betterAuthSessionCookie"
export const setBetterAuthSessionCookie = (cookie: string) => store.set(BetterAuthKey, cookie)
export const getBetterAuthSessionCookie = (): string | null => store.get(BetterAuthKey)
export const getBetterAuthSessionCookie = () => store.get(BetterAuthKey)
export const cleanBetterAuthSessionCookie = () => store.set(BetterAuthKey, null)

const UserKey = "user"
Expand Down
4 changes: 2 additions & 2 deletions apps/main/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function refreshBound(window: BrowserWindow, timeout = 0) {
setTimeout(() => {
// FIXME: workaround for theme bug in full screen mode
const size = window?.getSize()
window?.setSize(size[0] + 1, size[1] + 1)
window?.setSize(size[0], size[1])
window?.setSize(size[0]! + 1, size[1]! + 1)
window?.setSize(size[0]!, size[1]!)
}, timeout)
}
2 changes: 1 addition & 1 deletion apps/main/src/modules/language-detection/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const detectCodeStringLanguage = async function* (codeString: string) {
logger.debug("no model results", codeString)
return
}
const firstModelResult = adjustLanguageConfidence(modelResults[0])
const firstModelResult = adjustLanguageConfidence(modelResults[0]!)
if (firstModelResult.confidence < expectedRelativeConfidence) {
logger.debug("first model result confidence is less than expected relative confidence")
return
Expand Down
43 changes: 21 additions & 22 deletions apps/main/src/tipc/reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,32 @@ export const readerRoute = {
.input<{
id: string
text: string
voice: string
}>()
.action(async ({ input }) => {
const { id, text } = input

.action(async ({ input, context: { sender } }) => {
const { id, text, voice } = input
if (!text) {
return null
}

const window = BrowserWindow.fromWebContents(sender)
if (!window) return

// It's ok to set voice every time, because it will be cached by msedge-tts
await tts
.setMetadata(voice, OUTPUT_FORMAT.WEBM_24KHZ_16BIT_MONO_OPUS)
.catch((error: unknown) => {
console.error("Failed to set voice", error)
if (error instanceof Error) {
return callWindowExpose(window).toast.error(error.message, {
duration: 1000,
})
}
return callWindowExpose(window).toast.error("Failed to set voice", {
duration: 1000,
})
})

const filePath = path.join(app.getPath("userData"), `${id}.webm`)
if (fs.existsSync(filePath)) {
return filePath
Expand All @@ -62,25 +80,6 @@ export const readerRoute = {
}
}),

setVoice: t.procedure.input<string>().action(async ({ input, context: { sender } }) => {
const window = BrowserWindow.fromWebContents(sender)
if (!window) return

await tts
.setMetadata(input, OUTPUT_FORMAT.WEBM_24KHZ_16BIT_MONO_OPUS)
.catch((error: unknown) => {
console.error("Failed to set voice", error)
if (error instanceof Error) {
return callWindowExpose(window).toast.error(error.message, {
duration: 1000,
})
}
return callWindowExpose(window).toast.error("Failed to set voice", {
duration: 1000,
})
})
}),

detectCodeStringLanguage: t.procedure
.input<{ codeString: string }>()
.action(async ({ input }) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/main/src/updater/custom-github-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export class CustomGitHubProvider extends BaseGitHubProvider<GithubUpdateInfo> {
if (hrefElement === null) continue

// This Release's Tag
const hrefTag = hrefElement[1]
const hrefTag = hrefElement[1]!
// Get Channel from this release's tag
// If it is null, we believe it is stable version
const hrefChannel = (semver.prerelease(hrefTag)?.[0] as string) || "stable"
Expand Down
2 changes: 1 addition & 1 deletion apps/main/src/updater/hot-updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const getLatestReleaseTag = async () => {

// Search the top nightly release
const nightlyRelease = json.find((item) => item.prerelease)
if (!nightlyRelease) return json[0].tag_name
if (!nightlyRelease) return json[0]!.tag_name
return nightlyRelease.tag_name
}
}
Expand Down
7 changes: 1 addition & 6 deletions apps/main/src/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,7 @@ export function createWindow(
}
export const windowStateStoreKey = "windowState"
export const createMainWindow = () => {
const windowState = store.get(windowStateStoreKey) as {
height: number
width: number
x: number
y: number
} | null
const windowState = store.get(windowStateStoreKey)
const primaryDisplay = screen.getPrimaryDisplay()
const { workArea } = primaryDisplay

Expand Down
4 changes: 3 additions & 1 deletion apps/main/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
"compilerOptions": {
"composite": true,
"outDir": "dist",
"types": ["electron-vite/node"],
"types": ["electron-vite/node", "@follow/types/vite"],
"moduleResolution": "Bundler",
"noImplicitReturns": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"baseUrl": ".",
"paths": {
"@pkg": ["../../package.json"],
Expand Down
16 changes: 14 additions & 2 deletions apps/mobile/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { resolve } from "node:path"

import type { ConfigContext, ExpoConfig } from "expo/config"

import PKG from "./package.json"

// const roundedIconPath = resolve(__dirname, "../../resources/icon.png")
const iconPath = resolve(__dirname, "./assets/icon.png")
const adaptiveIconPath = resolve(__dirname, "./assets/adaptive-icon.png")

export default ({ config }: ConfigContext): ExpoConfig => ({
...config,

extra: {
eas: {
projectId: "a6335b14-fb84-45aa-ba80-6f6ab8926920",
Expand All @@ -23,7 +25,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({

name: "Follow",
slug: "follow",
version: "1.0.0",
version: process.env.NODE_ENV === "development" ? "dev" : PKG.version,
orientation: "portrait",
icon: iconPath,
scheme: "follow",
Expand All @@ -50,6 +52,13 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
favicon: iconPath,
},
plugins: [
[
"expo-document-picker",
{
iCloudContainerEnvironment: "Production",
},
],
"expo-localization",
[
"expo-router",
{
Expand All @@ -65,6 +74,8 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
},
},
],
"expo-build-properties",
"expo-sqlite",
[
"expo-font",
{
Expand All @@ -89,6 +100,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
},
],
"expo-apple-authentication",
"expo-av",
[require("./scripts/with-follow-assets.js")],
[require("./scripts/with-follow-app-delegate.js")],
"expo-secure-store",
Expand Down
3 changes: 2 additions & 1 deletion apps/mobile/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { DOMProps } from "expo/dom"
import type { FC } from "react"
import type WebView from "react-native-webview"

declare global {
export type WebComponent<P = object> = FC<P & { dom?: DOMProps }>
export type WebComponent<P = object> = FC<P & { dom?: DOMProps } & React.RefAttributes<WebView>>
}
export {}
Loading

0 comments on commit 452f7fc

Please sign in to comment.