mirror of
https://github.com/yang991178/fluent-reader.git
synced 2025-02-17 20:21:05 +01:00
add font customization
This commit is contained in:
parent
cf38cc00c8
commit
bba895a95e
@ -1,10 +1,3 @@
|
||||
# Build the MAS app
|
||||
CSC_IDENTITY_AUTO_DISCOVERY=false npx electron-builder -c electron-builder-mas.yml --mac mas:universal
|
||||
# Add ElectronTeamID to Info.plist
|
||||
sed -i '' -e 's/<\/dict>/<key>ElectronTeamID<\/key><string>EM8VE646TZ<\/string><\/dict>/g' "bin/darwin/universal/mas-universal/Fluent Reader.app/Contents/Info.plist"
|
||||
|
||||
printf "......................\nresignAndPackage start\n\n"
|
||||
|
||||
# Name of your app.
|
||||
APP="Fluent Reader"
|
||||
# Your Certificate name.
|
||||
@ -21,6 +14,17 @@ PARENT_PLIST="build/entitlements.mas.plist"
|
||||
CHILD_PLIST="build/entitlements.mas.inherit.plist"
|
||||
LOGINHELPER_PLIST="build/entitlements.mas.loginhelper.plist"
|
||||
FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks"
|
||||
|
||||
# Build universal binary for font-list
|
||||
# FONTLIST_PATH="node_modules/font-list/libs/darwin/fontlist.m"
|
||||
# clang -arch arm64 -arch x86_64 "$FONTLIST_PATH" -fmodules -o "dist/fontlist"
|
||||
# Build the MAS app
|
||||
CSC_IDENTITY_AUTO_DISCOVERY=false npx electron-builder -c electron-builder-mas.yml --mac mas:universal
|
||||
# Add ElectronTeamID to Info.plist
|
||||
sed -i '' -e 's/<\/dict>/<key>ElectronTeamID<\/key><string>EM8VE646TZ<\/string><\/dict>/g' "bin/darwin/universal/mas-universal/Fluent Reader.app/Contents/Info.plist"
|
||||
|
||||
printf "......................\nresignAndPackage start\n\n"
|
||||
codesign --deep --force --verify --verbose=4 --timestamp --options runtime --entitlements "$CHILD_PLIST" -s "$APP_KEY" "$APP_PATH/Contents/Resources/app.asar.unpacked/dist/fontlist"
|
||||
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Electron Framework"
|
||||
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib"
|
||||
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib"
|
||||
@ -44,4 +48,4 @@ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacO
|
||||
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH"
|
||||
productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH"
|
||||
|
||||
printf "\nresignAndPackage end\n......................\n"
|
||||
printf "\nresignAndPackage end\n......................\n"
|
||||
|
5
dist/article/article.css
vendored
5
dist/article/article.css
vendored
@ -128,6 +128,11 @@ article code {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1;
|
||||
}
|
||||
article pre {
|
||||
word-break: normal;
|
||||
overflow-wrap: normal;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
article blockquote {
|
||||
border-left: 2px solid var(--gray);
|
||||
margin: 1em 0;
|
||||
|
4
dist/article/article.html
vendored
4
dist/article/article.html
vendored
@ -3,14 +3,14 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy"
|
||||
content="default-src 'none'; script-src-elem 'sha256-sLDWrq1tUAO8IyyqmUckFqxbXYfZ2/3TEUmtxH8Unf0=' 'sha256-OOzJH14UHiDzBx2LDF/KOAR+BVrHdNzZ2fZvPaqCMhY='; img-src http: https: data:; style-src 'self' 'unsafe-inline'; frame-src http: https:; media-src http: https:; connect-src https: http:">
|
||||
content="default-src 'none'; script-src-elem 'sha256-sLDWrq1tUAO8IyyqmUckFqxbXYfZ2/3TEUmtxH8Unf0=' 'sha256-iOdZeo0zvgcSuiH/7/dXCOHo7s0cn2XtsidqVOcHBjo='; img-src http: https: data:; style-src 'self' 'unsafe-inline'; frame-src http: https:; media-src http: https:; connect-src https: http:">
|
||||
<title>Article</title>
|
||||
<link rel="stylesheet" href="article.css" />
|
||||
<script integrity="sha256-sLDWrq1tUAO8IyyqmUckFqxbXYfZ2/3TEUmtxH8Unf0=" src="mercury.web.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
<script integrity="sha256-OOzJH14UHiDzBx2LDF/KOAR+BVrHdNzZ2fZvPaqCMhY=" src="article.js"></script>
|
||||
<script integrity="sha256-iOdZeo0zvgcSuiH/7/dXCOHo7s0cn2XtsidqVOcHBjo=" src="article.js"></script>
|
||||
<!-- Run "cat article.js | openssl dgst -sha256 -binary | openssl enc -base64 -A" for hash -->
|
||||
</body>
|
||||
</html>
|
2
dist/article/article.js
vendored
2
dist/article/article.js
vendored
@ -20,6 +20,8 @@ async function getArticle(url) {
|
||||
}
|
||||
}
|
||||
document.documentElement.style.fontSize = get("s") + "px"
|
||||
let font = get("f")
|
||||
if (font) document.body.style.fontFamily = `"${font}"`
|
||||
let url = get("u")
|
||||
getArticle(url).then(article => {
|
||||
let domParser = new DOMParser()
|
||||
|
BIN
dist/fontlist
vendored
Executable file
BIN
dist/fontlist
vendored
Executable file
Binary file not shown.
29
dist/fonts.vbs
vendored
Normal file
29
dist/fonts.vbs
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
Option Explicit
|
||||
|
||||
Dim objShell, objFSO, objFile, objFolder
|
||||
Dim objFolderItem, colItems, objFont
|
||||
Dim strFileName
|
||||
|
||||
|
||||
Const FONTS = &H14& ' Fonts Folder
|
||||
|
||||
' Instantiate Objects
|
||||
Set objShell = CreateObject("Shell.Application")
|
||||
Set objFolder = objShell.Namespace(FONTS)
|
||||
Set objFolderItem = objFolder.Self
|
||||
Set colItems = objFolder.Items
|
||||
Set objFSO = CreateObject("Scripting.FileSystemObject")
|
||||
|
||||
For Each objFont in colItems
|
||||
WScript.StdOut.WriteLine(objFont.Path & vbtab & objFont.Name)
|
||||
Next
|
||||
|
||||
Set objShell = nothing
|
||||
Set objFile = nothing
|
||||
Set objFolder = nothing
|
||||
Set objFolderItem = nothing
|
||||
Set colItems = nothing
|
||||
Set objFont = nothing
|
||||
Set objFSO = nothing
|
||||
|
||||
wscript.quit
|
@ -4,7 +4,10 @@ productName: Fluent Reader
|
||||
copyright: Copyright © 2020 Haoyuan Liu
|
||||
files:
|
||||
- "./dist/**/*"
|
||||
- "!./dist/fonts.vbs"
|
||||
- "!**/*.js.map"
|
||||
asarUnpack:
|
||||
- "./dist/fontlist"
|
||||
directories:
|
||||
output: "./bin/${platform}/${arch}/"
|
||||
mac:
|
||||
|
@ -3,6 +3,7 @@ productName: Fluent Reader
|
||||
copyright: Copyright © 2020 Haoyuan Liu
|
||||
files:
|
||||
- "./dist/**/*"
|
||||
- "!./dist/fontlist"
|
||||
- "!**/*.js.map"
|
||||
directories:
|
||||
output: "./bin/${platform}/${arch}/"
|
||||
|
948
package-lock.json
generated
948
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -31,6 +31,7 @@
|
||||
"electron-react-devtools": "^0.5.3",
|
||||
"electron-store": "^5.2.0",
|
||||
"electron-window-state": "^5.0.3",
|
||||
"font-list": "^1.4.2",
|
||||
"hard-source-webpack-plugin": "^0.13.1",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"js-md5": "^0.7.3",
|
||||
|
@ -75,6 +75,13 @@ const settingsBridge = {
|
||||
ipcRenderer.invoke("set-font-size", size)
|
||||
},
|
||||
|
||||
getFont: (): string => {
|
||||
return ipcRenderer.sendSync("get-font")
|
||||
},
|
||||
setFont: (font: string) => {
|
||||
ipcRenderer.invoke("set-font", font)
|
||||
},
|
||||
|
||||
getFetchInterval: (): number => {
|
||||
return ipcRenderer.sendSync("get-fetch-interval")
|
||||
},
|
||||
|
@ -170,11 +170,16 @@ const utilsBridge = {
|
||||
destroyTouchBar: () => {
|
||||
ipcRenderer.invoke("touchbar-destroy")
|
||||
},
|
||||
|
||||
initFontList: (): Promise<Array<string>> => {
|
||||
return ipcRenderer.invoke("init-font-list")
|
||||
},
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
utils: typeof utilsBridge
|
||||
fontList: Array<string>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ type ArticleProps = {
|
||||
}
|
||||
|
||||
type ArticleState = {
|
||||
fontFamily: string
|
||||
fontSize: number
|
||||
loadWebpage: boolean
|
||||
loadFull: boolean
|
||||
@ -53,7 +54,8 @@ class Article extends React.Component<ArticleProps, ArticleState> {
|
||||
constructor(props: ArticleProps) {
|
||||
super(props)
|
||||
this.state = {
|
||||
fontSize: this.getFontSize(),
|
||||
fontFamily: window.settings.getFont(),
|
||||
fontSize: window.settings.getFontSize(),
|
||||
loadWebpage: props.source.openTarget === SourceOpenTarget.Webpage,
|
||||
loadFull: props.source.openTarget === SourceOpenTarget.FullContent,
|
||||
fullContent: "",
|
||||
@ -68,15 +70,16 @@ class Article extends React.Component<ArticleProps, ArticleState> {
|
||||
this.loadFull()
|
||||
}
|
||||
|
||||
getFontSize = () => {
|
||||
return window.settings.getFontSize()
|
||||
}
|
||||
setFontSize = (size: number) => {
|
||||
window.settings.setFontSize(size)
|
||||
this.setState({ fontSize: size })
|
||||
}
|
||||
setFont = (font: string) => {
|
||||
window.settings.setFont(font)
|
||||
this.setState({ fontFamily: font })
|
||||
}
|
||||
|
||||
fontMenuProps = (): IContextualMenuProps => ({
|
||||
fontSizeMenuProps = (): IContextualMenuProps => ({
|
||||
items: FONT_SIZE_OPTIONS.map(size => ({
|
||||
key: String(size),
|
||||
text: String(size),
|
||||
@ -86,6 +89,16 @@ class Article extends React.Component<ArticleProps, ArticleState> {
|
||||
})),
|
||||
})
|
||||
|
||||
fontFamilyMenuProps = (): IContextualMenuProps => ({
|
||||
items: window.fontList.map((font, idx) => ({
|
||||
key: String(idx),
|
||||
text: font === "" ? intl.get("default") : font,
|
||||
canCheck: true,
|
||||
checked: this.state.fontFamily === font,
|
||||
onClick: () => this.setFont(font)
|
||||
}))
|
||||
})
|
||||
|
||||
updateTextDirection = (direction: SourceTextDirection) => {
|
||||
this.props.updateSourceTextDirection(this.props.source, direction)
|
||||
}
|
||||
@ -154,10 +167,17 @@ class Article extends React.Component<ArticleProps, ArticleState> {
|
||||
},
|
||||
{
|
||||
key: "fontMenu",
|
||||
text: intl.get("article.font"),
|
||||
iconProps: { iconName: "Font" },
|
||||
disabled: this.state.loadWebpage,
|
||||
subMenuProps: this.fontFamilyMenuProps(),
|
||||
},
|
||||
{
|
||||
key: "fontSizeMenu",
|
||||
text: intl.get("article.fontSize"),
|
||||
iconProps: { iconName: "FontSize" },
|
||||
disabled: this.state.loadWebpage,
|
||||
subMenuProps: this.fontMenuProps(),
|
||||
subMenuProps: this.fontSizeMenuProps(),
|
||||
},
|
||||
{
|
||||
key: "directionMenu",
|
||||
@ -334,7 +354,9 @@ class Article extends React.Component<ArticleProps, ArticleState> {
|
||||
</>
|
||||
)
|
||||
)
|
||||
return `article/article.html?a=${a}&h=${h}&s=${
|
||||
return `article/article.html?a=${a}&h=${h}&f=${
|
||||
encodeURIComponent(this.state.fontFamily)
|
||||
}&s=${
|
||||
this.state.fontSize
|
||||
}&d=${
|
||||
this.props.source.textDir
|
||||
|
@ -26,6 +26,11 @@ window.utils.addMainContextListener((pos, text) => {
|
||||
store.dispatch(openTextMenu(pos, text))
|
||||
})
|
||||
|
||||
window.fontList = [""]
|
||||
window.utils.initFontList().then((fonts) => {
|
||||
window.fontList.push(...fonts)
|
||||
})
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<Root />
|
||||
|
@ -122,6 +122,14 @@ ipcMain.handle("set-font-size", (_, size: number) => {
|
||||
store.set(FONT_SIZE_STORE_KEY, size)
|
||||
})
|
||||
|
||||
const FONT_STORE_KEY = "fontFamily"
|
||||
ipcMain.on("get-font", event => {
|
||||
event.returnValue = store.get(FONT_STORE_KEY, "")
|
||||
})
|
||||
ipcMain.handle("set-font", (_, font: string) => {
|
||||
store.set(FONT_STORE_KEY, font)
|
||||
})
|
||||
|
||||
ipcMain.on("get-all-settings", event => {
|
||||
let output = {}
|
||||
for (let [key, value] of store) {
|
||||
|
@ -10,6 +10,7 @@ import { WindowManager } from "./window"
|
||||
import fs = require("fs")
|
||||
import { ImageCallbackTypes, TouchBarTexts } from "../schema-types"
|
||||
import { initMainTouchBar } from "./touchbar"
|
||||
import fontList = require('font-list')
|
||||
|
||||
export function setUtilsListeners(manager: WindowManager) {
|
||||
async function openExternal(url: string, background = false) {
|
||||
@ -283,4 +284,10 @@ export function setUtilsListeners(manager: WindowManager) {
|
||||
ipcMain.handle("touchbar-destroy", () => {
|
||||
if (manager.hasWindow()) manager.mainWindow.setTouchBar(null)
|
||||
})
|
||||
|
||||
ipcMain.handle("init-font-list", () => {
|
||||
return fontList.getFonts({
|
||||
disableQuoting: true,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ export type SchemaTypes = {
|
||||
locale: string
|
||||
sourceGroups: SourceGroup[]
|
||||
fontSize: number
|
||||
fontFamily: string
|
||||
menuOn: boolean
|
||||
fetchInterval: number
|
||||
searchEngine: SearchEngines
|
||||
|
@ -18,6 +18,7 @@
|
||||
"confirmMarkAll": "Do you really want to mark all articles on this page as read?",
|
||||
"confirm": "Confirm",
|
||||
"cancel": "Cancel",
|
||||
"default": "Default",
|
||||
"time": {
|
||||
"now": "now",
|
||||
"m": "m",
|
||||
@ -70,7 +71,8 @@
|
||||
"textDir": "Text direction",
|
||||
"LTR": "Left-to-right",
|
||||
"RTL": "Right-to-left",
|
||||
"Vertical": "Vertical"
|
||||
"Vertical": "Vertical",
|
||||
"font": "Font"
|
||||
},
|
||||
"context": {
|
||||
"share": "Share",
|
||||
|
@ -18,6 +18,7 @@
|
||||
"confirmMarkAll": "确认将本页所有文章标为已读?",
|
||||
"confirm": "确认",
|
||||
"cancel": "取消",
|
||||
"default": "默认",
|
||||
"time": {
|
||||
"now": "now",
|
||||
"m": "m",
|
||||
@ -70,7 +71,8 @@
|
||||
"textDir": "文本方向",
|
||||
"LTR": "从左到右",
|
||||
"RTL": "从右到左",
|
||||
"Vertical": "纵书"
|
||||
"Vertical": "纵书",
|
||||
"font": "字体"
|
||||
},
|
||||
"context": {
|
||||
"share": "分享",
|
||||
|
@ -18,6 +18,7 @@
|
||||
"confirmMarkAll": "確認將本頁所有文章標為已讀?",
|
||||
"confirm": "確認",
|
||||
"cancel": "取消",
|
||||
"default": "預設",
|
||||
"time": {
|
||||
"now": "now",
|
||||
"m": "m",
|
||||
@ -70,7 +71,8 @@
|
||||
"textDir": "文本方向",
|
||||
"LTR": "從左到右",
|
||||
"RTL": "從右到左",
|
||||
"Vertical": "縱書"
|
||||
"Vertical": "縱書",
|
||||
"font": "字體"
|
||||
},
|
||||
"context": {
|
||||
"share": "分享",
|
||||
|
@ -23,6 +23,9 @@ module.exports = [
|
||||
path: __dirname + "/dist",
|
||||
filename: "electron.js",
|
||||
},
|
||||
node: {
|
||||
__dirname: false
|
||||
},
|
||||
plugins: [new HardSourceWebpackPlugin()],
|
||||
},
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user