This commit is contained in:
刘浩远 2020-06-05 15:25:48 +08:00
parent 8debcfe7e4
commit 9bdcf4ea34
12 changed files with 78 additions and 54 deletions

Binary file not shown.

46
dist/styles.css vendored
View File

@ -1,11 +1,6 @@
@font-face {
font-family: "Source Han Sans";
src: url("SourceHanSansSC-Regular.otf");
}
html, body {
background-color: #faf9f8;
font-family: "Source Han Sans", sans-serif;
font-family: "Source Han Sans SC Regular", "Microsoft YaHei", sans-serif;
height: 100%;
overflow: hidden;
margin: 0;
@ -101,12 +96,15 @@ i.ms-Nav-chevron {
position: relative;
z-index: 10;
}
nav.hide-btns .btn-group .btn {
nav.menu-on .btn-group .btn, nav.hide-btns .btn-group .btn {
display: none;
}
nav.hide-btns .btn-group .btn.system {
nav.menu-on .btn-group .btn.system, nav.hide-btns .btn-group .btn.system {
display: inline-block;
}
.btn-group .btn.system.menu-on {
color: #fff;
}
.btn-group .btn:hover {
background-color: #0001;
}
@ -132,8 +130,8 @@ nav.hide-btns .btn-group .btn.system {
background-color: #f1707a;
color: #fff;
}
.btn-group .btn.system.on {
color: #fff;
.btn-group .btn.inline-block-wide {
display: none;
}
.menu-container {
@ -242,6 +240,34 @@ img.favicon {
z-index: 1;
}
@media (min-width: 1721px) {
#root > nav.menu-on {
padding-left: 296px;
}
nav.menu-on .btn-group .btn {
display: inline-block;
}
.btn-group .btn.system.menu-on {
color: #000;
}
.menu-container {
width: 280px;
}
.menu-container .menu {
background-color: #edebe9;
}
.main.menu-on {
padding-left: 280px;
}
nav.menu-on .btn-group .btn.hide-wide, .menu .btn-group .btn.hide-wide {
display: none;
}
.btn-group .btn.inline-block-wide {
display: inline-block;
}
}
.cards-feed-container {
display: inline-flex;
flex-wrap: wrap;

View File

@ -1,18 +1,17 @@
import * as React from "react"
import { Icon } from "@fluentui/react/lib/Icon"
import { Nav, INavLink, INavLinkGroup } from "office-ui-fabric-react/lib/Nav"
import { MenuStatus } from "../scripts/models/app"
import { SourceGroup } from "../scripts/models/page"
import { SourceState, RSSSource } from "../scripts/models/source"
import { ALL } from "../scripts/models/feed"
import { AnimationClassNames } from "@fluentui/react"
export type MenuProps = {
status: MenuStatus,
status: boolean,
selected: string,
sources: SourceState,
groups: SourceGroup[],
closeMenu: () => void,
toggleMenu: () => void,
allArticles: () => void,
selectSourceGroup: (group: SourceGroup, menuKey: string) => void,
selectSource: (source: RSSSource) => void
@ -74,11 +73,12 @@ export class Menu extends React.Component<MenuProps> {
})
render() {
return this.props.status == MenuStatus.Hidden ? null : (
<div className="menu-container" onClick={this.props.closeMenu}>
return this.props.status ? (
<div className="menu-container" onClick={this.props.toggleMenu}>
<div className="menu" onClick={(e) => e.stopPropagation()}>
<div className="btn-group">
<a className="btn" title="关闭菜单" onClick={this.props.closeMenu}><Icon iconName="Back" /></a>
<a className="btn hide-wide" title="关闭菜单" onClick={this.props.toggleMenu}><Icon iconName="Back" /></a>
<a className="btn inline-block-wide" title="关闭菜单" onClick={this.props.toggleMenu}><Icon iconName="GlobalNavButton" /></a>
</div>
<div className="nav-wrapper">
<Nav
@ -91,6 +91,6 @@ export class Menu extends React.Component<MenuProps> {
</div>
</div>
</div>
)
) : null
}
}

View File

@ -1,7 +1,7 @@
import * as React from "react"
import { ipcRenderer, remote } from "electron"
import { Icon } from "@fluentui/react/lib/Icon"
import { AppState, MenuStatus } from "../scripts/models/app"
import { AppState } from "../scripts/models/app"
type NavProps = {
state: AppState,
@ -49,8 +49,8 @@ class Nav extends React.Component<NavProps, NavState> {
canFetch = () => this.props.state.sourceInit && this.props.state.feedInit && !this.props.state.fetchingItems
fetching = () => !this.canFetch() ? " fetching" : ""
menuOn = () => this.props.state.menu == MenuStatus.Open ? " on" : ""
hideButtons = () => (this.props.state.menu == MenuStatus.Open || this.props.state.settings.display) ? "hide-btns" : ""
menuOn = () => this.props.state.menu ? " menu-on" : ""
hideButtons = () => this.props.state.settings.display ? "hide-btns" : ""
fetch = () => {
if (this.canFetch()) this.props.fetch()
@ -58,9 +58,9 @@ class Nav extends React.Component<NavProps, NavState> {
render() {
return (
<nav className={this.hideButtons()}>
<nav className={this.hideButtons() + this.menuOn()}>
<div className="btn-group">
<a className="btn" title="菜单" onClick={this.props.menu}><Icon iconName="GlobalNavButton" /></a>
<a className="btn hide-wide" title="菜单" onClick={this.props.menu}><Icon iconName="GlobalNavButton" /></a>
</div>
<span className="title">{this.props.state.title}</span>
<div className="btn-group" style={{float:"right"}}>

View File

@ -3,6 +3,7 @@ import { FeedIdType } from "../scripts/models/feed"
import { FeedContainer } from "../containers/feed-container"
type PageProps = {
menuOn: boolean
settingsOn: boolean
feeds: FeedIdType[]
}
@ -11,7 +12,7 @@ class Page extends React.Component<PageProps> {
render = () => (
<>
{this.props.settingsOn ? null :
<div className="main">
<div className={"main" + (this.props.menuOn ? " menu-on" : "")}>
{this.props.feeds.map(fid => (
<FeedContainer feedId={fid} key={fid} />
))}

View File

@ -2,12 +2,12 @@ import { connect } from "react-redux"
import { createSelector } from "reselect"
import { RootState } from "../scripts/reducer"
import { Menu } from "../components/menu"
import { closeMenu } from "../scripts/models/app"
import { toggleMenu } from "../scripts/models/app"
import { selectAllArticles, selectSources, SourceGroup } from "../scripts/models/page"
import { initFeeds } from "../scripts/models/feed"
import { RSSSource } from "../scripts/models/source"
const getStatus = (state: RootState) => state.app.menu
const getStatus = (state: RootState) => state.app.menu && state.app.sourceInit
const getKey = (state: RootState) => state.app.menuKey
const getSources = (state: RootState) => state.sources
const getGroups = (state: RootState) => state.page.sourceGroups
@ -23,7 +23,7 @@ const mapStateToProps = createSelector(
)
const mapDispatchToProps = dispatch => ({
closeMenu: () => dispatch(closeMenu()),
toggleMenu: () => dispatch(toggleMenu()),
allArticles: () => {
dispatch(selectAllArticles()),
dispatch(initFeeds())

View File

@ -2,7 +2,7 @@ import { connect } from "react-redux"
import { createSelector } from "reselect"
import { RootState } from "../scripts/reducer"
import { fetchItems } from "../scripts/models/item"
import { openMenu, toggleLogMenu, toggleSettings } from "../scripts/models/app"
import { toggleMenu, toggleLogMenu, toggleSettings } from "../scripts/models/app"
import Nav from "../components/nav"
const getState = (state: RootState) => state.app
@ -13,7 +13,7 @@ const mapStateToProps = createSelector(getState, (state) => ({
const mapDispatchToProps = (dispatch) => ({
fetch: () => dispatch(fetchItems()),
menu: () => dispatch(openMenu()),
menu: () => dispatch(toggleMenu()),
logs: () => dispatch(toggleLogMenu()),
settings: () => dispatch(toggleSettings())
})

View File

@ -5,12 +5,14 @@ import Page from "../components/page"
const getFeeds = (state: RootState) => state.page.feedId
const getSettings = (state: RootState) => state.app.settings.display
const getMenu = (state: RootState) => state.app.menu
const mapStateToProps = createSelector(
[getFeeds, getSettings],
(feeds, settingsOn) => ({
[getFeeds, getSettings, getMenu],
(feeds, settingsOn, menuOn) => ({
feeds: [feeds],
settingsOn: settingsOn
settingsOn: settingsOn,
menuOn: menuOn
})
)

View File

@ -14,7 +14,7 @@ import { AppDispatch, setProxy } from "./scripts/utils"
setProxy()
loadTheme({ defaultFontStyle: { fontFamily: '"Source Han Sans", sans-serif' } })
loadTheme({ defaultFontStyle: { fontFamily: '"Source Han Sans SC Regular", "Microsoft YaHei", sans-serif' } })
initializeIcons("icons/")
const store = createStore(

View File

@ -1,6 +1,6 @@
import { RSSSource, INIT_SOURCES, SourceActionTypes, ADD_SOURCE, UPDATE_SOURCE, DELETE_SOURCE } from "./source"
import { RSSItem, ItemActionTypes, FETCH_ITEMS, fetchItems } from "./item"
import { ActionStatus, AppThunk } from "../utils"
import { RSSItem, ItemActionTypes, FETCH_ITEMS } from "./item"
import { ActionStatus, AppThunk, getWindowBreakpoint } from "../utils"
import { INIT_FEEDS, FeedActionTypes, ALL, initFeeds } from "./feed"
import { PageActionTypes, SELECT_PAGE, PageType, selectAllArticles, SourceGroupActionTypes, UPDATE_SOURCE_GROUP, ADD_SOURCE_TO_GROUP, DELETE_SOURCE_GROUP, REMOVE_SOURCE_FROM_GROUP } from "./page"
@ -8,10 +8,6 @@ export enum ContextMenuType {
Hidden, Item
}
export enum MenuStatus {
Hidden, Open, Pinned
}
export enum AppLogType {
Info, Warning, Failure
}
@ -34,7 +30,7 @@ export class AppState {
sourceInit = false
feedInit = false
fetchingItems = false
menu = MenuStatus.Hidden
menu = getWindowBreakpoint()
menuKey = ALL
title = "全部文章"
settings = {
@ -79,11 +75,10 @@ export type ContextMenuActionTypes = CloseContextMenuAction | OpenItemMenuAction
export const TOGGLE_LOGS = "TOGGLE_LOGS"
export interface LogMenuActionType { type: typeof TOGGLE_LOGS }
export const OPEN_MENU = "OPEN_MENU"
export const CLOSE_MENU = "CLOSE_MENU"
export const TOGGLE_MENU = "TOGGLE_MENU"
export interface MenuActionTypes {
type: typeof OPEN_MENU | typeof CLOSE_MENU
type: typeof TOGGLE_MENU
}
export const TOGGLE_SETTINGS = "TOGGLE_SETTINGS"
@ -105,8 +100,7 @@ export function openItemMenu(item: RSSItem, event: React.MouseEvent): ContextMen
}
}
export const openMenu = () => ({ type: OPEN_MENU })
export const closeMenu = () => ({ type: CLOSE_MENU })
export const toggleMenu = () => ({ type: TOGGLE_MENU })
export const toggleLogMenu = () => ({ type: TOGGLE_LOGS })
export const toggleSettings = () => ({ type: TOGGLE_SETTINGS })
export const saveSettings = () => ({ type: SAVE_SETTINGS })
@ -218,13 +212,13 @@ export function appReducer(
switch (action.pageType) {
case PageType.AllArticles: return {
...state,
menu: MenuStatus.Hidden,
menu: state.menu && action.keepMenu,
menuKey: ALL,
title: "全部文章"
}
case PageType.Sources: return {
...state,
menu: MenuStatus.Hidden,
menu: state.menu && action.keepMenu,
menuKey: action.menuKey,
title: action.title
}
@ -243,13 +237,9 @@ export function appReducer(
target: action.item
}
}
case OPEN_MENU: return {
case TOGGLE_MENU: return {
...state,
menu: MenuStatus.Open
}
case CLOSE_MENU: return {
...state,
menu: MenuStatus.Hidden
menu: !state.menu
}
case SAVE_SETTINGS: return {
...state,

View File

@ -1,7 +1,7 @@
import fs = require("fs")
import { SourceActionTypes, ADD_SOURCE, DELETE_SOURCE, addSource } from "./source"
import { ALL, SOURCE } from "./feed"
import { ActionStatus, AppThunk, domParser, AppDispatch } from "../utils"
import { ActionStatus, AppThunk, domParser, AppDispatch, getWindowBreakpoint } from "../utils"
import { saveSettings } from "./app"
const GROUPS_STORE_KEY = "sourceGroups"
@ -43,6 +43,7 @@ interface SelectPageAction {
type: typeof SELECT_PAGE
pageType: PageType
init: boolean
keepMenu: boolean
sids?: number[]
menuKey?: string
title?: string
@ -53,6 +54,7 @@ export type PageActionTypes = SelectPageAction
export function selectAllArticles(init = false): SelectPageAction {
return {
type: SELECT_PAGE,
keepMenu: getWindowBreakpoint(),
pageType: PageType.AllArticles,
init: init
}
@ -62,6 +64,7 @@ export function selectSources(sids: number[], menuKey: string, title: string) {
return {
type: SELECT_PAGE,
pageType: PageType.Sources,
keepMenu: getWindowBreakpoint(),
sids: sids,
menuKey: menuKey,
title: title,

View File

@ -80,4 +80,6 @@ export function openExternal(url: string) {
}
export const urlTest = (s: string) =>
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi.test(s)
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi.test(s)
export const getWindowBreakpoint = () => remote.getCurrentWindow().getSize()[0] >= 1721