mirror of
https://github.com/yang991178/fluent-reader.git
synced 2025-03-28 09:20:10 +01:00
toggle snippet / cover in list view
This commit is contained in:
parent
478a12c036
commit
f2d5ca0171
16
dist/styles/cards.css
vendored
16
dist/styles/cards.css
vendored
@ -195,22 +195,34 @@
|
|||||||
}
|
}
|
||||||
.list-card .data {
|
.list-card .data {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
margin: 8px 10px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.list-card .info {
|
.list-card .info {
|
||||||
margin: 8px 10px;
|
margin: 0 0 8px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
}
|
}
|
||||||
.list-card h3.title {
|
.list-card h3.title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin: 8px 10px;
|
margin: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
-webkit-line-clamp: 3;
|
-webkit-line-clamp: 3;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
}
|
}
|
||||||
|
.list-card p.snippet {
|
||||||
|
color: var(--neutralSecondary);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
margin: 4px 0 0;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
overflow: hidden;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
.magazine-card {
|
.magazine-card {
|
||||||
width: 700px;
|
width: 700px;
|
||||||
|
2
dist/styles/main.css
vendored
2
dist/styles/main.css
vendored
@ -239,7 +239,7 @@ body.darwin .list-main .article-search {
|
|||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1441px) {
|
@media (min-width: 1440px) {
|
||||||
#root > nav.menu-on {
|
#root > nav.menu-on {
|
||||||
padding-left: 296px;
|
padding-left: 296px;
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 86 KiB |
@ -1,4 +1,4 @@
|
|||||||
import { SourceGroup, ViewType, ThemeSettings, SearchEngines, ServiceConfigs } from "../schema-types"
|
import { SourceGroup, ViewType, ThemeSettings, SearchEngines, ServiceConfigs, ViewConfigs } from "../schema-types"
|
||||||
import { ipcRenderer } from "electron"
|
import { ipcRenderer } from "electron"
|
||||||
|
|
||||||
const settingsBridge = {
|
const settingsBridge = {
|
||||||
@ -96,6 +96,13 @@ const settingsBridge = {
|
|||||||
ipcRenderer.invoke("set-filter-type", filterType)
|
ipcRenderer.invoke("set-filter-type", filterType)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getViewConfigs: (view: ViewType): ViewConfigs => {
|
||||||
|
return ipcRenderer.sendSync("get-view-configs", view)
|
||||||
|
},
|
||||||
|
setViewConfigs: (view: ViewType, configs: ViewConfigs) => {
|
||||||
|
ipcRenderer.invoke("set-view-configs", view, configs)
|
||||||
|
},
|
||||||
|
|
||||||
getAll: () => {
|
getAll: () => {
|
||||||
return ipcRenderer.sendSync("get-all-settings") as Object
|
return ipcRenderer.sendSync("get-all-settings") as Object
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@ import { RSSSource, SourceOpenTarget } from "../../scripts/models/source"
|
|||||||
import { RSSItem } from "../../scripts/models/item"
|
import { RSSItem } from "../../scripts/models/item"
|
||||||
import { platformCtrl } from "../../scripts/utils"
|
import { platformCtrl } from "../../scripts/utils"
|
||||||
import { FeedFilter } from "../../scripts/models/feed"
|
import { FeedFilter } from "../../scripts/models/feed"
|
||||||
|
import { ViewConfigs } from "../../schema-types"
|
||||||
|
|
||||||
export namespace Card {
|
export namespace Card {
|
||||||
export type Props = {
|
export type Props = {
|
||||||
@ -10,6 +11,7 @@ export namespace Card {
|
|||||||
item: RSSItem
|
item: RSSItem
|
||||||
source: RSSSource
|
source: RSSSource
|
||||||
filter: FeedFilter
|
filter: FeedFilter
|
||||||
|
viewConfigs?: ViewConfigs
|
||||||
shortcuts: (item: RSSItem, e: KeyboardEvent) => void
|
shortcuts: (item: RSSItem, e: KeyboardEvent) => void
|
||||||
markRead: (item: RSSItem) => void
|
markRead: (item: RSSItem) => void
|
||||||
contextMenu: (feedId: string, item: RSSItem, e) => void
|
contextMenu: (feedId: string, item: RSSItem, e) => void
|
||||||
|
@ -2,6 +2,7 @@ import * as React from "react"
|
|||||||
import { Card } from "./card"
|
import { Card } from "./card"
|
||||||
import CardInfo from "./info"
|
import CardInfo from "./info"
|
||||||
import Highlights from "./highlights"
|
import Highlights from "./highlights"
|
||||||
|
import { ViewConfigs } from "../../schema-types"
|
||||||
|
|
||||||
const className = (props: Card.Props) => {
|
const className = (props: Card.Props) => {
|
||||||
let cn = ["card", "list-card"]
|
let cn = ["card", "list-card"]
|
||||||
@ -15,12 +16,15 @@ const ListCard: React.FunctionComponent<Card.Props> = (props) => (
|
|||||||
{...Card.bindEventsToProps(props)}
|
{...Card.bindEventsToProps(props)}
|
||||||
data-iid={props.item._id}
|
data-iid={props.item._id}
|
||||||
data-is-focusable>
|
data-is-focusable>
|
||||||
{props.item.thumb ? (
|
{props.item.thumb && (props.viewConfigs & ViewConfigs.ShowCover) ? (
|
||||||
<div className="head"><img src={props.item.thumb} /></div>
|
<div className="head"><img src={props.item.thumb} /></div>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="data">
|
<div className="data">
|
||||||
<CardInfo source={props.source} item={props.item} />
|
<CardInfo source={props.source} item={props.item} />
|
||||||
<h3 className="title"><Highlights text={props.item.title} filter={props.filter} title /></h3>
|
<h3 className="title"><Highlights text={props.item.title} filter={props.filter} title /></h3>
|
||||||
|
{Boolean(props.viewConfigs & ViewConfigs.ShowSnippet) && (
|
||||||
|
<p className="snippet"><Highlights text={props.item.snippet} filter={props.filter} /></p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -6,7 +6,7 @@ import { ContextualMenu, IContextualMenuItem, ContextualMenuItemType, Directiona
|
|||||||
import { ContextMenuType } from "../scripts/models/app"
|
import { ContextMenuType } from "../scripts/models/app"
|
||||||
import { RSSItem } from "../scripts/models/item"
|
import { RSSItem } from "../scripts/models/item"
|
||||||
import { ContextReduxProps } from "../containers/context-menu-container"
|
import { ContextReduxProps } from "../containers/context-menu-container"
|
||||||
import { ViewType, ImageCallbackTypes } from "../schema-types"
|
import { ViewType, ImageCallbackTypes, ViewConfigs } from "../schema-types"
|
||||||
import { FilterType } from "../scripts/models/feed"
|
import { FilterType } from "../scripts/models/feed"
|
||||||
|
|
||||||
export type ContextMenuProps = ContextReduxProps & {
|
export type ContextMenuProps = ContextReduxProps & {
|
||||||
@ -18,6 +18,7 @@ export type ContextMenuProps = ContextReduxProps & {
|
|||||||
text?: string
|
text?: string
|
||||||
url?: string
|
url?: string
|
||||||
viewType?: ViewType
|
viewType?: ViewType
|
||||||
|
viewConfigs?: ViewConfigs
|
||||||
filter?: FilterType
|
filter?: FilterType
|
||||||
sids?: number[]
|
sids?: number[]
|
||||||
showItem: (feedId: string, item: RSSItem) => void
|
showItem: (feedId: string, item: RSSItem) => void
|
||||||
@ -26,6 +27,7 @@ export type ContextMenuProps = ContextReduxProps & {
|
|||||||
toggleStarred: (item: RSSItem) => void
|
toggleStarred: (item: RSSItem) => void
|
||||||
toggleHidden: (item: RSSItem) => void
|
toggleHidden: (item: RSSItem) => void
|
||||||
switchView: (viewType: ViewType) => void
|
switchView: (viewType: ViewType) => void
|
||||||
|
setViewConfigs: (configs: ViewConfigs) => void
|
||||||
switchFilter: (filter: FilterType) => void
|
switchFilter: (filter: FilterType) => void
|
||||||
toggleFilter: (filter: FilterType) => void
|
toggleFilter: (filter: FilterType) => void
|
||||||
markAllRead: (sids: number[], date?: Date, before?: boolean) => void
|
markAllRead: (sids: number[], date?: Date, before?: boolean) => void
|
||||||
@ -142,7 +144,35 @@ export class ContextMenu extends React.Component<ContextMenuProps> {
|
|||||||
key: "copyURL",
|
key: "copyURL",
|
||||||
text: intl.get("context.copyURL"),
|
text: intl.get("context.copyURL"),
|
||||||
onClick: () => { window.utils.writeClipboard(this.props.item.link) }
|
onClick: () => { window.utils.writeClipboard(this.props.item.link) }
|
||||||
}
|
},
|
||||||
|
...(this.props.viewConfigs !== undefined ? [
|
||||||
|
{
|
||||||
|
key: "divider_2",
|
||||||
|
itemType: ContextualMenuItemType.Divider,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "view",
|
||||||
|
text: intl.get("context.view"),
|
||||||
|
subMenuProps: {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
key: "showCover",
|
||||||
|
text: intl.get("context.showCover"),
|
||||||
|
canCheck: true,
|
||||||
|
checked: Boolean(this.props.viewConfigs & ViewConfigs.ShowCover),
|
||||||
|
onClick: () => this.props.setViewConfigs(this.props.viewConfigs ^ ViewConfigs.ShowCover)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "showSnippet",
|
||||||
|
text: intl.get("context.showSnippet"),
|
||||||
|
canCheck: true,
|
||||||
|
checked: Boolean(this.props.viewConfigs & ViewConfigs.ShowSnippet),
|
||||||
|
onClick: () => this.props.setViewConfigs(this.props.viewConfigs ^ ViewConfigs.ShowSnippet)
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
] : [])
|
||||||
]
|
]
|
||||||
case ContextMenuType.Text: {
|
case ContextMenuType.Text: {
|
||||||
const items: IContextualMenuItem[] = this.props.text? [
|
const items: IContextualMenuItem[] = this.props.text? [
|
||||||
|
@ -2,13 +2,14 @@ import * as React from "react"
|
|||||||
import { RSSItem } from "../../scripts/models/item"
|
import { RSSItem } from "../../scripts/models/item"
|
||||||
import { FeedReduxProps } from "../../containers/feed-container"
|
import { FeedReduxProps } from "../../containers/feed-container"
|
||||||
import { RSSFeed, FeedFilter } from "../../scripts/models/feed"
|
import { RSSFeed, FeedFilter } from "../../scripts/models/feed"
|
||||||
import { ViewType } from "../../schema-types"
|
import { ViewType, ViewConfigs } from "../../schema-types"
|
||||||
import CardsFeed from "./cards-feed"
|
import CardsFeed from "./cards-feed"
|
||||||
import ListFeed from "./list-feed"
|
import ListFeed from "./list-feed"
|
||||||
|
|
||||||
export type FeedProps = FeedReduxProps & {
|
export type FeedProps = FeedReduxProps & {
|
||||||
feed: RSSFeed
|
feed: RSSFeed
|
||||||
viewType: ViewType
|
viewType: ViewType
|
||||||
|
viewConfigs?: ViewConfigs
|
||||||
items: RSSItem[]
|
items: RSSItem[]
|
||||||
sourceMap: Object
|
sourceMap: Object
|
||||||
filter: FeedFilter
|
filter: FeedFilter
|
||||||
|
@ -17,6 +17,7 @@ class ListFeed extends React.Component<FeedProps> {
|
|||||||
item: item,
|
item: item,
|
||||||
source: this.props.sourceMap[item.source],
|
source: this.props.sourceMap[item.source],
|
||||||
filter: this.props.filter,
|
filter: this.props.filter,
|
||||||
|
viewConfigs: this.props.viewConfigs,
|
||||||
shortcuts: this.props.shortcuts,
|
shortcuts: this.props.shortcuts,
|
||||||
markRead: this.props.markRead,
|
markRead: this.props.markRead,
|
||||||
contextMenu: this.props.contextMenu,
|
contextMenu: this.props.contextMenu,
|
||||||
|
@ -4,21 +4,23 @@ import { RootState } from "../scripts/reducer"
|
|||||||
import { ContextMenuType, closeContextMenu, toggleSettings } from "../scripts/models/app"
|
import { ContextMenuType, closeContextMenu, toggleSettings } from "../scripts/models/app"
|
||||||
import { ContextMenu } from "../components/context-menu"
|
import { ContextMenu } from "../components/context-menu"
|
||||||
import { RSSItem, markRead, markUnread, toggleStarred, toggleHidden, markAllRead } from "../scripts/models/item"
|
import { RSSItem, markRead, markUnread, toggleStarred, toggleHidden, markAllRead } from "../scripts/models/item"
|
||||||
import { showItem, switchView, switchFilter, toggleFilter } from "../scripts/models/page"
|
import { showItem, switchView, switchFilter, toggleFilter, setViewConfigs } from "../scripts/models/page"
|
||||||
import { ViewType } from "../schema-types"
|
import { ViewType, ViewConfigs } from "../schema-types"
|
||||||
import { FilterType } from "../scripts/models/feed"
|
import { FilterType } from "../scripts/models/feed"
|
||||||
|
|
||||||
const getContext = (state: RootState) => state.app.contextMenu
|
const getContext = (state: RootState) => state.app.contextMenu
|
||||||
const getViewType = (state: RootState) => state.page.viewType
|
const getViewType = (state: RootState) => state.page.viewType
|
||||||
const getFilter = (state: RootState) => state.page.filter
|
const getFilter = (state: RootState) => state.page.filter
|
||||||
|
const getViewConfigs = (state: RootState) => state.page.viewConfigs
|
||||||
|
|
||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(
|
||||||
[getContext, getViewType, getFilter],
|
[getContext, getViewType, getFilter, getViewConfigs],
|
||||||
(context, viewType, filter) => {
|
(context, viewType, filter, viewConfigs) => {
|
||||||
switch (context.type) {
|
switch (context.type) {
|
||||||
case ContextMenuType.Item: return {
|
case ContextMenuType.Item: return {
|
||||||
type: context.type,
|
type: context.type,
|
||||||
event: context.event,
|
event: context.event,
|
||||||
|
viewConfigs: viewConfigs,
|
||||||
item: context.target[0],
|
item: context.target[0],
|
||||||
feedId: context.target[1]
|
feedId: context.target[1]
|
||||||
}
|
}
|
||||||
@ -65,6 +67,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
window.settings.setDefaultView(viewType)
|
window.settings.setDefaultView(viewType)
|
||||||
dispatch(switchView(viewType))
|
dispatch(switchView(viewType))
|
||||||
},
|
},
|
||||||
|
setViewConfigs: (configs: ViewConfigs) => dispatch(setViewConfigs(configs)),
|
||||||
switchFilter: (filter: FilterType) => dispatch(switchFilter(filter)),
|
switchFilter: (filter: FilterType) => dispatch(switchFilter(filter)),
|
||||||
toggleFilter: (filter: FilterType) => dispatch(toggleFilter(filter)),
|
toggleFilter: (filter: FilterType) => dispatch(toggleFilter(filter)),
|
||||||
markAllRead: (sids: number[], date?: Date, before?: boolean) => {
|
markAllRead: (sids: number[], date?: Date, before?: boolean) => {
|
||||||
|
@ -18,16 +18,18 @@ const getItems = (state: RootState) => state.items
|
|||||||
const getFeed = (state: RootState, props: FeedContainerProps) => state.feeds[props.feedId]
|
const getFeed = (state: RootState, props: FeedContainerProps) => state.feeds[props.feedId]
|
||||||
const getFilter = (state: RootState) => state.page.filter
|
const getFilter = (state: RootState) => state.page.filter
|
||||||
const getView = (_, props: FeedContainerProps) => props.viewType
|
const getView = (_, props: FeedContainerProps) => props.viewType
|
||||||
|
const getViewConfigs = (state: RootState) => state.page.viewConfigs
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
const makeMapStateToProps = () => {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
[getSources, getItems, getFeed, getView, getFilter],
|
[getSources, getItems, getFeed, getView, getFilter, getViewConfigs],
|
||||||
(sources, items, feed, viewType, filter) => ({
|
(sources, items, feed, viewType, filter, viewConfigs) => ({
|
||||||
feed: feed,
|
feed: feed,
|
||||||
items: feed.iids.map(iid => items[iid]),
|
items: feed.iids.map(iid => items[iid]),
|
||||||
sourceMap: sources,
|
sourceMap: sources,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
viewType: viewType
|
viewType: viewType,
|
||||||
|
viewConfigs: viewConfigs,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import Store = require("electron-store")
|
import Store = require("electron-store")
|
||||||
import { SchemaTypes, SourceGroup, ViewType, ThemeSettings, SearchEngines,
|
import { SchemaTypes, SourceGroup, ViewType, ThemeSettings, SearchEngines,
|
||||||
SyncService, ServiceConfigs } from "../schema-types"
|
SyncService, ServiceConfigs, ViewConfigs } from "../schema-types"
|
||||||
import { ipcMain, session, nativeTheme, app } from "electron"
|
import { ipcMain, session, nativeTheme, app } from "electron"
|
||||||
import { WindowManager } from "./window"
|
import { WindowManager } from "./window"
|
||||||
|
|
||||||
@ -153,3 +153,22 @@ ipcMain.on("get-filter-type", (event) => {
|
|||||||
ipcMain.handle("set-filter-type", (_, filterType: number) => {
|
ipcMain.handle("set-filter-type", (_, filterType: number) => {
|
||||||
store.set(FILTER_TYPE_STORE_KEY, filterType)
|
store.set(FILTER_TYPE_STORE_KEY, filterType)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const LIST_CONFIGS_STORE_KEY = "listViewConfigs"
|
||||||
|
ipcMain.on("get-view-configs", (event, view: ViewType) => {
|
||||||
|
switch (view) {
|
||||||
|
case ViewType.List:
|
||||||
|
event.returnValue = store.get(LIST_CONFIGS_STORE_KEY, ViewConfigs.ShowCover)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
event.returnValue = undefined
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
ipcMain.handle("set-view-configs", (_, view: ViewType, configs: ViewConfigs) => {
|
||||||
|
switch (view) {
|
||||||
|
case ViewType.List:
|
||||||
|
store.set(LIST_CONFIGS_STORE_KEY, configs)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
@ -22,6 +22,11 @@ export const enum ViewType {
|
|||||||
Cards, List, Magazine, Compact, Customized
|
Cards, List, Magazine, Compact, Customized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const enum ViewConfigs {
|
||||||
|
ShowCover = 1 << 0,
|
||||||
|
ShowSnippet = 1 << 1,
|
||||||
|
}
|
||||||
|
|
||||||
export const enum ThemeSettings {
|
export const enum ThemeSettings {
|
||||||
Default = "system",
|
Default = "system",
|
||||||
Light = "light",
|
Light = "light",
|
||||||
@ -70,4 +75,5 @@ export type SchemaTypes = {
|
|||||||
searchEngine: SearchEngines
|
searchEngine: SearchEngines
|
||||||
serviceConfigs: ServiceConfigs
|
serviceConfigs: ServiceConfigs
|
||||||
filterType: number
|
filterType: number
|
||||||
|
listViewConfigs: ViewConfigs
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,9 @@
|
|||||||
"saveImageAs": "Save image as …",
|
"saveImageAs": "Save image as …",
|
||||||
"copyImage": "Copy image",
|
"copyImage": "Copy image",
|
||||||
"copyImageURL": "Copy image link",
|
"copyImageURL": "Copy image link",
|
||||||
"caseSensitive": "Case sensitive"
|
"caseSensitive": "Case sensitive",
|
||||||
|
"showCover": "Show cover",
|
||||||
|
"showSnippet": "Show snippet"
|
||||||
},
|
},
|
||||||
"searchEngine": {
|
"searchEngine": {
|
||||||
"name": "Search engine",
|
"name": "Search engine",
|
||||||
|
@ -89,7 +89,9 @@
|
|||||||
"saveImageAs": "将图像另存为",
|
"saveImageAs": "将图像另存为",
|
||||||
"copyImage": "复制图像",
|
"copyImage": "复制图像",
|
||||||
"copyImageURL": "复制图像链接",
|
"copyImageURL": "复制图像链接",
|
||||||
"caseSensitive": "区分大小写"
|
"caseSensitive": "区分大小写",
|
||||||
|
"showCover": "显示封面",
|
||||||
|
"showSnippet": "显示摘要"
|
||||||
},
|
},
|
||||||
"searchEngine": {
|
"searchEngine": {
|
||||||
"name": "搜索引擎",
|
"name": "搜索引擎",
|
||||||
|
@ -3,10 +3,11 @@ import { getWindowBreakpoint, AppThunk, ActionStatus } from "../utils"
|
|||||||
import { RSSItem, markRead } from "./item"
|
import { RSSItem, markRead } from "./item"
|
||||||
import { SourceActionTypes, DELETE_SOURCE } from "./source"
|
import { SourceActionTypes, DELETE_SOURCE } from "./source"
|
||||||
import { toggleMenu } from "./app"
|
import { toggleMenu } from "./app"
|
||||||
import { ViewType } from "../../schema-types"
|
import { ViewType, ViewConfigs } from "../../schema-types"
|
||||||
|
|
||||||
export const SELECT_PAGE = "SELECT_PAGE"
|
export const SELECT_PAGE = "SELECT_PAGE"
|
||||||
export const SWITCH_VIEW = "SWITCH_VIEW"
|
export const SWITCH_VIEW = "SWITCH_VIEW"
|
||||||
|
export const SET_VIEW_CONFIGS = "SET_VIEW_CONFIGS"
|
||||||
export const SHOW_ITEM = "SHOW_ITEM"
|
export const SHOW_ITEM = "SHOW_ITEM"
|
||||||
export const SHOW_OFFSET_ITEM = "SHOW_OFFSET_ITEM"
|
export const SHOW_OFFSET_ITEM = "SHOW_OFFSET_ITEM"
|
||||||
export const DISMISS_ITEM = "DISMISS_ITEM"
|
export const DISMISS_ITEM = "DISMISS_ITEM"
|
||||||
@ -33,6 +34,11 @@ interface SwitchViewAction {
|
|||||||
viewType: ViewType
|
viewType: ViewType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SetViewConfigsAction {
|
||||||
|
type: typeof SET_VIEW_CONFIGS
|
||||||
|
configs: ViewConfigs
|
||||||
|
}
|
||||||
|
|
||||||
interface ShowItemAction {
|
interface ShowItemAction {
|
||||||
type: typeof SHOW_ITEM
|
type: typeof SHOW_ITEM
|
||||||
feedId: string
|
feedId: string
|
||||||
@ -48,7 +54,7 @@ interface DismissItemAction { type: typeof DISMISS_ITEM }
|
|||||||
interface ToggleSearchAction { type: typeof TOGGLE_SEARCH }
|
interface ToggleSearchAction { type: typeof TOGGLE_SEARCH }
|
||||||
|
|
||||||
export type PageActionTypes = SelectPageAction | SwitchViewAction | ShowItemAction
|
export type PageActionTypes = SelectPageAction | SwitchViewAction | ShowItemAction
|
||||||
| DismissItemAction | ApplyFilterAction | ToggleSearchAction
|
| DismissItemAction | ApplyFilterAction | ToggleSearchAction | SetViewConfigsAction
|
||||||
|
|
||||||
export function selectAllArticles(init = false): AppThunk {
|
export function selectAllArticles(init = false): AppThunk {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
@ -86,6 +92,16 @@ export function switchView(viewType: ViewType): PageActionTypes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setViewConfigs(configs: ViewConfigs): AppThunk {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
window.settings.setViewConfigs(getState().page.viewType, configs)
|
||||||
|
dispatch({
|
||||||
|
type: "SET_VIEW_CONFIGS",
|
||||||
|
configs: configs
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function showItem(feedId: string, item: RSSItem): AppThunk {
|
export function showItem(feedId: string, item: RSSItem): AppThunk {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const state = getState()
|
const state = getState()
|
||||||
@ -218,6 +234,7 @@ export function performSearch(query: string): AppThunk {
|
|||||||
|
|
||||||
export class PageState {
|
export class PageState {
|
||||||
viewType = window.settings.getDefaultView()
|
viewType = window.settings.getDefaultView()
|
||||||
|
viewConfigs = window.settings.getViewConfigs(window.settings.getDefaultView())
|
||||||
filter = new FeedFilter()
|
filter = new FeedFilter()
|
||||||
feedId = ALL
|
feedId = ALL
|
||||||
itemId = null as string
|
itemId = null as string
|
||||||
@ -247,7 +264,12 @@ export function pageReducer(
|
|||||||
case SWITCH_VIEW: return {
|
case SWITCH_VIEW: return {
|
||||||
...state,
|
...state,
|
||||||
viewType: action.viewType,
|
viewType: action.viewType,
|
||||||
itemId: null
|
viewConfigs: window.settings.getViewConfigs(action.viewType),
|
||||||
|
itemId: null
|
||||||
|
}
|
||||||
|
case SET_VIEW_CONFIGS: return {
|
||||||
|
...state,
|
||||||
|
viewConfigs: action.configs
|
||||||
}
|
}
|
||||||
case APPLY_FILTER: return {
|
case APPLY_FILTER: return {
|
||||||
...state,
|
...state,
|
||||||
|
@ -124,7 +124,7 @@ export function htmlDecode(input: string) {
|
|||||||
export const urlTest = (s: 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 = () => window.outerWidth >= 1441
|
export const getWindowBreakpoint = () => window.outerWidth >= 1440
|
||||||
|
|
||||||
export const cutText = (s: string, length: number) => {
|
export const cutText = (s: string, length: number) => {
|
||||||
return (s.length <= length) ? s : s.slice(0, length) + "…"
|
return (s.length <= length) ? s : s.slice(0, length) + "…"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user