read content in webview
This commit is contained in:
parent
143a295024
commit
288907fdae
36
dist/article/article.css
vendored
Normal file
36
dist/article/article.css
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
html, body {
|
||||
font-family: "Segoe UI Regular", "Source Han Sans SC Regular", "Microsoft YaHei", sans-serif;
|
||||
margin: 16px 48px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0078d4;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover, a:active {
|
||||
color: #004578;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#main > p.title {
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
article {
|
||||
line-height: 1.6;
|
||||
}
|
||||
article img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
article figure {
|
||||
margin: 16px 0;
|
||||
text-align: center;
|
||||
}
|
||||
article figure figcaption {
|
||||
font-size: .875rem;
|
||||
color: #484644;
|
||||
}
|
14
dist/article/article.html
vendored
Normal file
14
dist/article/article.html
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; img-src *; style-src 'self' 'unsafe-inline'; frame-src *">
|
||||
<title>Hello World!</title>
|
||||
<link rel="stylesheet" href="article.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
<script src="article.js"></script>
|
||||
</body>
|
||||
</html>
|
10
dist/article/article.js
vendored
Normal file
10
dist/article/article.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
function get(name) {
|
||||
if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(location.search))
|
||||
return decodeURIComponent(name[1]);
|
||||
}
|
||||
let main = document.getElementById("main")
|
||||
main.innerHTML = decodeURIComponent(window.atob(get("h")))
|
||||
document.addEventListener("click", event => {
|
||||
event.preventDefault()
|
||||
if (event.target.href) ipcRenderer.sendToHost("request-navigation", event.target.href)
|
||||
})
|
1
dist/article/preload.js
vendored
Normal file
1
dist/article/preload.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
global.ipcRenderer = require("electron").ipcRenderer
|
37
dist/styles.css
vendored
37
dist/styles.css
vendored
@ -117,7 +117,7 @@ nav.menu-on .btn-group .btn, nav.hide-btns .btn-group .btn {
|
||||
nav.menu-on .btn-group .btn.system, nav.hide-btns .btn-group .btn.system {
|
||||
display: inline-block;
|
||||
}
|
||||
.btn-group .btn.system.menu-on {
|
||||
nav.menu-on .btn-group .btn.system {
|
||||
color: #fff;
|
||||
}
|
||||
.btn-group .btn:hover {
|
||||
@ -139,17 +139,17 @@ nav.menu-on .btn-group .btn.system, nav.hide-btns .btn-group .btn.system {
|
||||
}
|
||||
.btn-group .btn.close:hover {
|
||||
background-color: #e81123;
|
||||
color: #fff;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-group .btn.close:active {
|
||||
background-color: #f1707a;
|
||||
color: #fff;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-group .btn.inline-block-wide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-container {
|
||||
.menu-container, .article-container {
|
||||
position: fixed;
|
||||
z-index: 5;
|
||||
left: 0;
|
||||
@ -159,6 +159,10 @@ nav.menu-on .btn-group .btn.system, nav.hide-btns .btn-group .btn.system {
|
||||
background-color: #0008;
|
||||
backdrop-filter: saturate(150%) blur(20px);
|
||||
}
|
||||
.article-container {
|
||||
z-index: 6;
|
||||
background-color: #fff6;
|
||||
}
|
||||
.menu-container .menu {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@ -266,7 +270,7 @@ img.favicon {
|
||||
nav.menu-on .btn-group .btn {
|
||||
display: inline-block;
|
||||
}
|
||||
.btn-group .btn.system.menu-on {
|
||||
nav.menu-on .btn-group .btn.system {
|
||||
color: #000;
|
||||
}
|
||||
.menu-container {
|
||||
@ -298,16 +302,29 @@ img.favicon {
|
||||
}
|
||||
}
|
||||
|
||||
.article-wrapper {
|
||||
margin: 32px auto 0;
|
||||
width: 860px;
|
||||
height: calc(100% - 50px);
|
||||
background-color: #fff;
|
||||
box-shadow: 0 6.4px 14.4px 0 rgba(0,0,0,.132), 0 1.2px 3.6px 0 rgba(0,0,0,.108);
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.article webview {
|
||||
width: 100%;
|
||||
height: calc(100vh - 50px);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.cards-feed-container {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
justify-content: space-around;
|
||||
padding: 12px;
|
||||
}
|
||||
.cards-feed-container > div {
|
||||
flex-grow: 1;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
.cards-feed-container > div.load-more-wrapper, .flex-fix {
|
||||
text-align: center;
|
||||
}
|
||||
.cards-feed-container > div.load-more-wrapper {
|
||||
width: 100%;
|
||||
|
50
src/components/article.tsx
Normal file
50
src/components/article.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
import * as React from "react"
|
||||
import { renderToString } from "react-dom/server"
|
||||
import { RSSItem } from "../scripts/models/item"
|
||||
import { openExternal } from "../scripts/utils"
|
||||
|
||||
type ArticleProps = {
|
||||
item: RSSItem
|
||||
dismiss: () => void
|
||||
}
|
||||
|
||||
class Article extends React.Component<ArticleProps> {
|
||||
webview: HTMLWebViewElement
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
ipcHandler = event => {
|
||||
if (event.channel === "request-navigation") {
|
||||
openExternal(event.args[0])
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.webview = document.getElementById("article")
|
||||
this.webview.addEventListener("ipc-message", this.ipcHandler)
|
||||
this.webview.addEventListener("will-navigate", this.props.dismiss)
|
||||
}
|
||||
|
||||
componentWillUnmount = () => {
|
||||
this.webview.removeEventListener("ipc-message", this.ipcHandler)
|
||||
this.webview.removeEventListener("will-navigate", this.props.dismiss)
|
||||
}
|
||||
|
||||
articleView = () => "article/article.html?h=" + window.btoa(encodeURIComponent(renderToString(<>
|
||||
<p className="title">{this.props.item.title}</p>
|
||||
<article dangerouslySetInnerHTML={{__html: this.props.item.content}}></article>
|
||||
</>)))
|
||||
|
||||
render = () => (
|
||||
<div className="article">
|
||||
<webview
|
||||
id="article"
|
||||
src={this.articleView()}
|
||||
preload="article/preload.js" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Article
|
@ -2,12 +2,16 @@ import * as React from "react"
|
||||
import { openExternal } from "../../scripts/utils"
|
||||
import { RSSSource } from "../../scripts/models/source"
|
||||
import { RSSItem } from "../../scripts/models/item"
|
||||
import { FeedIdType } from "../../scripts/models/feed"
|
||||
|
||||
export interface CardProps {
|
||||
feedId: FeedIdType
|
||||
index: number
|
||||
item: RSSItem
|
||||
source: RSSSource
|
||||
markRead: Function
|
||||
contextMenu: Function
|
||||
markRead: (item: RSSItem) => void
|
||||
contextMenu: (item: RSSItem, e) => void
|
||||
showItem: (fid: FeedIdType, index: number) => void
|
||||
}
|
||||
|
||||
export class Card extends React.Component<CardProps> {
|
||||
@ -19,7 +23,8 @@ export class Card extends React.Component<CardProps> {
|
||||
onClick = (e: React.MouseEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
this.openInBrowser()
|
||||
this.props.markRead(this.props.item)
|
||||
this.props.showItem(this.props.feedId, this.props.index)
|
||||
}
|
||||
|
||||
onMouseUp = (e: React.MouseEvent) => {
|
||||
|
@ -32,14 +32,16 @@ class CardsFeed extends Feed {
|
||||
return this.props.feed.loaded && (
|
||||
<div className="cards-feed-container">
|
||||
{
|
||||
this.props.items.map(item => (
|
||||
<div key={item.id}>
|
||||
<DefaultCard
|
||||
item={item}
|
||||
source={this.props.sourceMap[item.source]}
|
||||
markRead={this.props.markRead}
|
||||
contextMenu={this.props.contextMenu} />
|
||||
</div>
|
||||
this.props.items.map((item, index) => (
|
||||
<DefaultCard
|
||||
feedId={this.props.feed.id}
|
||||
index={index}
|
||||
key={item.id}
|
||||
item={item}
|
||||
source={this.props.sourceMap[item.source]}
|
||||
markRead={this.props.markRead}
|
||||
contextMenu={this.props.contextMenu}
|
||||
showItem={this.props.showItem} />
|
||||
))
|
||||
}
|
||||
{ this.flexFix() }
|
||||
|
@ -1,15 +1,16 @@
|
||||
import * as React from "react"
|
||||
import { RSSItem } from "../../scripts/models/item"
|
||||
import { FeedReduxProps } from "../../containers/feed-container"
|
||||
import { RSSFeed } from "../../scripts/models/feed"
|
||||
import { RSSFeed, FeedIdType } from "../../scripts/models/feed"
|
||||
|
||||
type FeedProps = FeedReduxProps & {
|
||||
feed: RSSFeed
|
||||
items: RSSItem[]
|
||||
sourceMap: Object
|
||||
markRead: Function
|
||||
contextMenu: Function
|
||||
loadMore: Function
|
||||
markRead: (item: RSSItem) => void
|
||||
contextMenu: (item: RSSItem, e) => void
|
||||
loadMore: (feed: RSSFeed) => void
|
||||
showItem: (fid: FeedIdType, index: number) => void
|
||||
}
|
||||
|
||||
export class Feed extends React.Component<FeedProps> { }
|
@ -8,6 +8,7 @@ import { AnimationClassNames } from "@fluentui/react"
|
||||
|
||||
export type MenuProps = {
|
||||
status: boolean,
|
||||
display: boolean,
|
||||
selected: string,
|
||||
sources: SourceState,
|
||||
groups: SourceGroup[],
|
||||
@ -73,8 +74,8 @@ export class Menu extends React.Component<MenuProps> {
|
||||
})
|
||||
|
||||
render() {
|
||||
return this.props.status ? (
|
||||
<div className="menu-container" onClick={this.props.toggleMenu}>
|
||||
return this.props.status && (
|
||||
<div className="menu-container" onClick={this.props.toggleMenu} style={{display: this.props.display ? "block" : "none"}}>
|
||||
<div className="menu" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="btn-group">
|
||||
<a className="btn hide-wide" title="关闭菜单" onClick={this.props.toggleMenu}><Icon iconName="Back" /></a>
|
||||
@ -91,6 +92,6 @@ export class Menu extends React.Component<MenuProps> {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
)
|
||||
}
|
||||
}
|
@ -79,11 +79,11 @@ class Nav extends React.Component<NavProps, NavState> {
|
||||
<a className="btn" title="视图"><Icon iconName="View" /></a>
|
||||
<a className="btn" title="选项" onClick={this.props.settings}><Icon iconName="Settings" /></a>
|
||||
<span className="seperator"></span>
|
||||
<a className={"btn system"+this.menuOn()} title="最小化" onClick={this.minimize} style={{fontSize: 12}}><Icon iconName="Remove" /></a>
|
||||
<a className={"btn system"+this.menuOn()} title="最大化" onClick={this.maximize}>
|
||||
<a className="btn system" title="最小化" onClick={this.minimize} style={{fontSize: 12}}><Icon iconName="Remove" /></a>
|
||||
<a className="btn system" title="最大化" onClick={this.maximize}>
|
||||
{this.state.maximized ? <Icon iconName="ChromeRestore" style={{fontSize: 11}} /> :<Icon iconName="Checkbox" style={{fontSize: 10}} />}
|
||||
</a>
|
||||
<a className={"btn system close"+this.menuOn()} title="关闭" onClick={this.close}><Icon iconName="Cancel" /></a>
|
||||
<a className="btn system close" title="关闭" onClick={this.close}><Icon iconName="Cancel" /></a>
|
||||
</div>
|
||||
{!this.canFetch() &&
|
||||
<ProgressIndicator
|
||||
|
@ -1,11 +1,17 @@
|
||||
import * as React from "react"
|
||||
import { FeedIdType } from "../scripts/models/feed"
|
||||
import { FeedContainer } from "../containers/feed-container"
|
||||
import { RSSItem } from "../scripts/models/item"
|
||||
import Article from "./article"
|
||||
import { dismissItem } from "../scripts/models/page"
|
||||
import { AnimationClassNames } from "@fluentui/react"
|
||||
|
||||
type PageProps = {
|
||||
menuOn: boolean
|
||||
settingsOn: boolean
|
||||
feeds: FeedIdType[]
|
||||
item: RSSItem
|
||||
dismissItem: () => void
|
||||
}
|
||||
|
||||
class Page extends React.Component<PageProps> {
|
||||
@ -17,6 +23,13 @@ class Page extends React.Component<PageProps> {
|
||||
<FeedContainer feedId={fid} key={fid} />
|
||||
))}
|
||||
</div>}
|
||||
{this.props.item && (
|
||||
<div className="article-container" onClick={this.props.dismissItem}>
|
||||
<div className={"article-wrapper " + AnimationClassNames.slideUpIn20} onClick={e => e.stopPropagation()}>
|
||||
<Article item={this.props.item} dismiss={dismissItem} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -2,9 +2,10 @@ import { connect } from "react-redux"
|
||||
import { createSelector } from "reselect"
|
||||
import { RootState } from "../scripts/reducer"
|
||||
import CardsFeed from "../components/feeds/cards-feed"
|
||||
import { markRead } from "../scripts/models/item"
|
||||
import { markRead, RSSItem } from "../scripts/models/item"
|
||||
import { openItemMenu } from "../scripts/models/app"
|
||||
import { FeedIdType, loadMore } from "../scripts/models/feed"
|
||||
import { FeedIdType, loadMore, RSSFeed } from "../scripts/models/feed"
|
||||
import { showItem } from "../scripts/models/page"
|
||||
|
||||
interface FeedContainerProps {
|
||||
feedId: FeedIdType
|
||||
@ -26,9 +27,10 @@ const makeMapStateToProps = () => {
|
||||
}
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
markRead: item => dispatch(markRead(item)),
|
||||
contextMenu: (item, e) => dispatch(openItemMenu(item, e)),
|
||||
loadMore: feed => dispatch(loadMore(feed))
|
||||
markRead: (item: RSSItem) => dispatch(markRead(item)),
|
||||
contextMenu: (item: RSSItem, e) => dispatch(openItemMenu(item, e)),
|
||||
loadMore: (feed: RSSFeed) => dispatch(loadMore(feed)),
|
||||
showItem: (fid: FeedIdType, index: number) => dispatch(showItem(fid, index))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,16 +8,16 @@ import { selectAllArticles, selectSources } from "../scripts/models/page"
|
||||
import { initFeeds } from "../scripts/models/feed"
|
||||
import { RSSSource } from "../scripts/models/source"
|
||||
|
||||
const getStatus = (state: RootState) => state.app.menu && state.app.sourceInit
|
||||
const getKey = (state: RootState) => state.app.menuKey
|
||||
const getApp = (state: RootState) => state.app
|
||||
const getSources = (state: RootState) => state.sources
|
||||
const getGroups = (state: RootState) => state.groups
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
[getStatus, getKey, getSources, getGroups],
|
||||
(status, key, sources, groups) => ({
|
||||
status: status,
|
||||
selected: key,
|
||||
[getApp, getSources, getGroups],
|
||||
(app, sources, groups) => ({
|
||||
status: app.sourceInit,
|
||||
display: app.menu,
|
||||
selected: app.menuKey,
|
||||
sources: sources,
|
||||
groups: groups
|
||||
})
|
||||
|
@ -2,19 +2,30 @@ import { connect } from "react-redux"
|
||||
import { createSelector } from "reselect"
|
||||
import { RootState } from "../scripts/reducer"
|
||||
import Page from "../components/page"
|
||||
import { AppDispatch } from "../scripts/utils"
|
||||
import { dismissItem } from "../scripts/models/page"
|
||||
|
||||
const getFeeds = (state: RootState) => state.page.feedId
|
||||
const getPage = (state: RootState) => state.page
|
||||
const getSettings = (state: RootState) => state.app.settings.display
|
||||
const getMenu = (state: RootState) => state.app.menu
|
||||
const getItems = (state: RootState) => state.items
|
||||
const getFeeds = (state: RootState) => state.feeds
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
[getFeeds, getSettings, getMenu],
|
||||
(feeds, settingsOn, menuOn) => ({
|
||||
feeds: [feeds],
|
||||
[getPage, getSettings, getMenu, getItems, getFeeds],
|
||||
(page, settingsOn, menuOn, items, feeds) => ({
|
||||
feeds: [page.feedId],
|
||||
settingsOn: settingsOn,
|
||||
menuOn: menuOn
|
||||
menuOn: menuOn,
|
||||
item: page.itemIndex >= 0 // && page.itemIndex < feeds[page.feedId].iids.length
|
||||
? items[feeds[page.feedId].iids[page.itemIndex]]
|
||||
: null
|
||||
})
|
||||
)
|
||||
|
||||
const PageContainer = connect(mapStateToProps)(Page)
|
||||
const mapDispatchToProps = (dispatch: AppDispatch) => ({
|
||||
dismissItem: () => dispatch(dismissItem())
|
||||
})
|
||||
|
||||
const PageContainer = connect(mapStateToProps, mapDispatchToProps)(Page)
|
||||
export default PageContainer
|
@ -5,6 +5,7 @@ import { RootState } from "../../scripts/reducer"
|
||||
import SourcesTab from "../../components/settings/sources"
|
||||
import { addSource, RSSSource, updateSource, deleteSource } from "../../scripts/models/source"
|
||||
import { importOPML } from "../../scripts/models/group"
|
||||
import { AppDispatch } from "../../scripts/utils"
|
||||
|
||||
const getSources = (state: RootState) => state.sources
|
||||
|
||||
@ -15,7 +16,7 @@ const mapStateToProps = createSelector(
|
||||
})
|
||||
)
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
const mapDispatchToProps = (dispatch: AppDispatch) => {
|
||||
return {
|
||||
addSource: (url: string) => dispatch(addSource(url)),
|
||||
updateSourceName: (source: RSSSource, name: string) => {
|
||||
@ -30,7 +31,7 @@ const mapDispatchToProps = dispatch => {
|
||||
properties: ["openFile"]
|
||||
}
|
||||
)
|
||||
if (path.length > 0) dispatch(importOPML(path[0]))
|
||||
if (path && path.length > 0) dispatch(importOPML(path[0]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ function createWindow() {
|
||||
minHeight: 600,
|
||||
frame: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
nodeIntegration: true,
|
||||
webviewTag: true
|
||||
}
|
||||
})
|
||||
mainWindowState.manage(mainWindow)
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src *; style-src 'self' 'unsafe-inline'; font-src 'self' https://static2.sharepointonline.com; connect-src *">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src *; style-src 'self' 'unsafe-inline'; font-src 'self' https://static2.sharepointonline.com; connect-src *; frame-src *">
|
||||
<title>Hello World!</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
|
@ -2,6 +2,8 @@ import { ALL, SOURCE, FeedIdType } from "./feed"
|
||||
import { getWindowBreakpoint } from "../utils"
|
||||
|
||||
export const SELECT_PAGE = "SELECT_PAGE"
|
||||
export const SHOW_ITEM = "SHOW_ITEM"
|
||||
export const DISMISS_ITEM = "DISMISS_ITEM"
|
||||
|
||||
export enum PageType {
|
||||
AllArticles, Sources, Page
|
||||
@ -17,9 +19,17 @@ interface SelectPageAction {
|
||||
title?: string
|
||||
}
|
||||
|
||||
export type PageActionTypes = SelectPageAction
|
||||
interface ShowItemAction {
|
||||
type: typeof SHOW_ITEM
|
||||
feedId: FeedIdType
|
||||
itemIndex: number
|
||||
}
|
||||
|
||||
export function selectAllArticles(init = false): SelectPageAction {
|
||||
interface DismissItemAction { type: typeof DISMISS_ITEM }
|
||||
|
||||
export type PageActionTypes = SelectPageAction | ShowItemAction | DismissItemAction
|
||||
|
||||
export function selectAllArticles(init = false): PageActionTypes {
|
||||
return {
|
||||
type: SELECT_PAGE,
|
||||
keepMenu: getWindowBreakpoint(),
|
||||
@ -28,7 +38,7 @@ export function selectAllArticles(init = false): SelectPageAction {
|
||||
}
|
||||
}
|
||||
|
||||
export function selectSources(sids: number[], menuKey: string, title: string) {
|
||||
export function selectSources(sids: number[], menuKey: string, title: string): PageActionTypes {
|
||||
return {
|
||||
type: SELECT_PAGE,
|
||||
pageType: PageType.Sources,
|
||||
@ -40,8 +50,19 @@ export function selectSources(sids: number[], menuKey: string, title: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export function showItem(feedId: FeedIdType, itemIndex: number): PageActionTypes {
|
||||
return {
|
||||
type: SHOW_ITEM,
|
||||
feedId: feedId,
|
||||
itemIndex: itemIndex
|
||||
}
|
||||
}
|
||||
|
||||
export const dismissItem = (): PageActionTypes => ({ type: DISMISS_ITEM })
|
||||
|
||||
export class PageState {
|
||||
feedId = ALL
|
||||
feedId = ALL as FeedIdType
|
||||
itemIndex = -1
|
||||
}
|
||||
|
||||
export function pageReducer(
|
||||
@ -61,6 +82,14 @@ export function pageReducer(
|
||||
}
|
||||
default: return state
|
||||
}
|
||||
case SHOW_ITEM: return {
|
||||
...state,
|
||||
itemIndex: action.itemIndex
|
||||
}
|
||||
case DISMISS_ITEM: return {
|
||||
...state,
|
||||
itemIndex: -1
|
||||
}
|
||||
default: return state
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user