1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00

fix: 新しい記事を書く時に発生するバグ一体

This commit is contained in:
Rokt33r
2015-11-22 15:03:48 +09:00
parent 7d9894bef7
commit 954b3e9fc5
7 changed files with 89 additions and 56 deletions

View File

@@ -225,36 +225,6 @@ function remap (state) {
let activeArticle = _.findWhere(articles, {key: status.articleKey}) let activeArticle = _.findWhere(articles, {key: status.articleKey})
if (activeArticle == null) activeArticle = articles[0] if (activeArticle == null) activeArticle = articles[0]
// remove Unsaved new article if user is not CREATE_MODE
if (status.mode !== CREATE_MODE) {
let targetIndex = _.findIndex(articles, article => article.status === NEW)
if (targetIndex >= 0) articles.splice(targetIndex, 1)
}
// switching CREATE_MODE
if (status.mode === CREATE_MODE) {
let newArticle = _.findWhere(articles, {status: 'NEW'})
let FolderKey = targetFolders.length > 0
? targetFolders[0].key
: folders[0].key
if (newArticle == null) {
newArticle = {
id: null,
key: keygen(),
title: '',
content: '',
mode: 'markdown',
tags: [],
FolderKey: FolderKey,
status: NEW
}
articles.unshift(newArticle)
}
activeArticle = newArticle
}
return { return {
folders, folders,
status, status,

View File

@@ -7,7 +7,6 @@ import MarkdownPreview from 'boost/components/MarkdownPreview'
import CodeEditor from 'boost/components/CodeEditor' import CodeEditor from 'boost/components/CodeEditor'
import { import {
IDLE_MODE, IDLE_MODE,
CREATE_MODE,
EDIT_MODE, EDIT_MODE,
switchMode, switchMode,
switchArticle, switchArticle,
@@ -15,6 +14,7 @@ import {
clearSearch, clearSearch,
lockStatus, lockStatus,
unlockStatus, unlockStatus,
clearNewArticle,
updateArticle, updateArticle,
destroyArticle, destroyArticle,
NEW NEW
@@ -114,7 +114,7 @@ export default class ArticleDetail extends React.Component {
componentDidUpdate (prevProps) { componentDidUpdate (prevProps) {
let isModeChanged = prevProps.status.mode !== this.props.status.mode let isModeChanged = prevProps.status.mode !== this.props.status.mode
if (isModeChanged && this.props.status.mode !== IDLE_MODE) { if (isModeChanged && this.props.status.mode === EDIT_MODE) {
ReactDOM.findDOMNode(this.refs.title).focus() ReactDOM.findDOMNode(this.refs.title).focus()
} }
} }
@@ -124,6 +124,7 @@ export default class ArticleDetail extends React.Component {
let isArticleChanged = nextProps.activeArticle != null && (nextProps.activeArticle.key !== this.state.article.key) let isArticleChanged = nextProps.activeArticle != null && (nextProps.activeArticle.key !== this.state.article.key)
let isModeChanged = nextProps.status.mode !== this.props.status.mode let isModeChanged = nextProps.status.mode !== this.props.status.mode
// Reset article input // Reset article input
if (isArticleChanged || (isModeChanged && nextProps.status.mode !== IDLE_MODE)) { if (isArticleChanged || (isModeChanged && nextProps.status.mode !== IDLE_MODE)) {
Object.assign(nextState, { Object.assign(nextState, {
@@ -248,12 +249,15 @@ export default class ArticleDetail extends React.Component {
let { activeArticle, dispatch } = this.props let { activeArticle, dispatch } = this.props
dispatch(unlockStatus()) dispatch(unlockStatus())
if (activeArticle.status === NEW) dispatch(switchArticle(null)) if (activeArticle.status === NEW) {
dispatch(clearNewArticle())
dispatch(switchArticle(null))
}
dispatch(switchMode(IDLE_MODE)) dispatch(switchMode(IDLE_MODE))
} }
handleSaveButtonClick (e) { handleSaveButtonClick (e) {
let { dispatch, folders, filters } = this.props let { dispatch, folders, status } = this.props
let article = this.state.article let article = this.state.article
let newArticle = Object.assign({}, article) let newArticle = Object.assign({}, article)
@@ -277,7 +281,7 @@ export default class ArticleDetail extends React.Component {
// Searchを初期化し、更新先のFolder filterをかける // Searchを初期化し、更新先のFolder filterをかける
// かかれていない時に // かかれていない時に
// Searchを初期化する // Searchを初期化する
if (filters.folder.length !== 0) dispatch(switchFolder(folder.name)) if (status.targetFolders.length > 0) dispatch(switchFolder(folder.name))
else dispatch(clearSearch()) else dispatch(clearSearch())
dispatch(switchArticle(newArticle.key)) dispatch(switchArticle(newArticle.key))
} }
@@ -319,8 +323,6 @@ export default class ArticleDetail extends React.Component {
let article = this.state.article let article = this.state.article
article.tags = tags article.tags = tags
this.setState({article: article})
let _isTagChanged = _.difference(article.tags, this.props.activeArticle.tags).length > 0 || _.difference(this.props.activeArticle.tags, article.tags).length > 0 let _isTagChanged = _.difference(article.tags, this.props.activeArticle.tags).length > 0 || _.difference(this.props.activeArticle.tags, article.tags).length > 0
let { isTitleChanged, isContentChanged, isArticleEdited, isModeChanged } = this.state let { isTitleChanged, isContentChanged, isArticleEdited, isModeChanged } = this.state
@@ -500,7 +502,6 @@ export default class ArticleDetail extends React.Component {
if (activeArticle == null) return this.renderEmpty() if (activeArticle == null) return this.renderEmpty()
switch (status.mode) { switch (status.mode) {
case CREATE_MODE:
case EDIT_MODE: case EDIT_MODE:
return this.renderEdit() return this.renderEdit()
case IDLE_MODE: case IDLE_MODE:

View File

@@ -1,10 +1,11 @@
import React, { PropTypes } from 'react' import React, { PropTypes } from 'react'
import { findWhere } from 'lodash' import { findWhere } from 'lodash'
import { setSearchFilter, switchFolder, switchMode, CREATE_MODE } from 'boost/actions' import { setSearchFilter, switchFolder, switchMode, switchArticle, updateArticle, EDIT_MODE } from 'boost/actions'
import { openModal } from 'boost/modal' import { openModal } from 'boost/modal'
import FolderMark from 'boost/components/FolderMark' import FolderMark from 'boost/components/FolderMark'
import Preferences from 'boost/components/modal/Preferences' import Preferences from 'boost/components/modal/Preferences'
import CreateNewFolder from 'boost/components/modal/CreateNewFolder' import CreateNewFolder from 'boost/components/modal/CreateNewFolder'
import keygen from 'boost/keygen'
import remote from 'remote' import remote from 'remote'
let userName = remote.getGlobal('process').env.USER let userName = remote.getGlobal('process').env.USER
@@ -65,9 +66,27 @@ export default class ArticleNavigator extends React.Component {
} }
handleNewPostButtonClick (e) { handleNewPostButtonClick (e) {
let { dispatch } = this.props let { dispatch, folders, status } = this.props
let { targetFolders } = status
dispatch(switchMode(CREATE_MODE)) let FolderKey = targetFolders.length > 0
? targetFolders[0].key
: folders[0].key
let newArticle = {
id: null,
key: keygen(),
title: '',
content: '',
mode: 'markdown',
tags: [],
FolderKey: FolderKey,
status: 'NEW'
}
dispatch(updateArticle(newArticle))
dispatch(switchArticle(newArticle.key, true))
dispatch(switchMode(EDIT_MODE))
} }
handleNewFolderButton (e) { handleNewFolderButton (e) {
@@ -94,7 +113,7 @@ export default class ArticleNavigator extends React.Component {
let folderElememts = folders.map((folder, index) => { let folderElememts = folders.map((folder, index) => {
let isActive = findWhere(targetFolders, {key: folder.key}) let isActive = findWhere(targetFolders, {key: folder.key})
let articleCount = allArticles.filter(article => article.FolderKey === folder.key).length let articleCount = allArticles.filter(article => article.FolderKey === folder.key && article.status !== 'NEW').length
return ( return (
<button onClick={e => this.handleFolderButtonClick(folder.name)(e)} key={'folder-' + folder.key} className={isActive ? 'active' : ''}> <button onClick={e => this.handleFolderButtonClick(folder.name)(e)} key={'folder-' + folder.key} className={isActive ? 'active' : ''}>

View File

@@ -1,4 +1,5 @@
// Action types // Action types
export const CLEAR_NEW_ARTICLE = 'CLEAR_NEW_ARTICLE'
export const ARTICLE_UPDATE = 'ARTICLE_UPDATE' export const ARTICLE_UPDATE = 'ARTICLE_UPDATE'
export const ARTICLE_DESTROY = 'ARTICLE_DESTROY' export const ARTICLE_DESTROY = 'ARTICLE_DESTROY'
export const FOLDER_CREATE = 'FOLDER_CREATE' export const FOLDER_CREATE = 'FOLDER_CREATE'
@@ -18,13 +19,18 @@ export const TOGGLE_TUTORIAL = 'TOGGLE_TUTORIAL'
// Status - mode // Status - mode
export const IDLE_MODE = 'IDLE_MODE' export const IDLE_MODE = 'IDLE_MODE'
export const CREATE_MODE = 'CREATE_MODE'
export const EDIT_MODE = 'EDIT_MODE' export const EDIT_MODE = 'EDIT_MODE'
// Article status // Article status
export const NEW = 'NEW' export const NEW = 'NEW'
// DB // DB
export function clearNewArticle () {
return {
type: CLEAR_NEW_ARTICLE
}
}
export function updateArticle (article) { export function updateArticle (article) {
return { return {
type: ARTICLE_UPDATE, type: ARTICLE_UPDATE,
@@ -84,10 +90,13 @@ export function switchMode (mode) {
} }
} }
export function switchArticle (articleKey) { export function switchArticle (articleKey, isNew) {
return { return {
type: SWITCH_ARTICLE, type: SWITCH_ARTICLE,
data: articleKey data: {
key: articleKey,
isNew: isNew
}
} }
} }

View File

@@ -1,6 +1,6 @@
import React, { PropTypes } from 'react' import React, { PropTypes } from 'react'
import store from 'boost/store' import store from 'boost/store'
import { unlockStatus } from 'boost/actions' import { unlockStatus, clearNewArticle } from 'boost/actions'
export default class EditedAlert extends React.Component { export default class EditedAlert extends React.Component {
handleNoButtonClick (e) { handleNoButtonClick (e) {
@@ -10,6 +10,7 @@ export default class EditedAlert extends React.Component {
handleYesButtonClick (e) { handleYesButtonClick (e) {
store.dispatch(unlockStatus()) store.dispatch(unlockStatus())
store.dispatch(this.props.action) store.dispatch(this.props.action)
store.dispatch(clearNewArticle())
this.props.close() this.props.close()
} }

View File

@@ -15,6 +15,7 @@ import {
// Article action type // Article action type
ARTICLE_UPDATE, ARTICLE_UPDATE,
ARTICLE_DESTROY, ARTICLE_DESTROY,
CLEAR_NEW_ARTICLE,
// Folder action type // Folder action type
FOLDER_CREATE, FOLDER_CREATE,
@@ -23,8 +24,7 @@ import {
FOLDER_REPLACE, FOLDER_REPLACE,
// view mode // view mode
IDLE_MODE, IDLE_MODE
CREATE_MODE
} from './actions' } from './actions'
import dataStore from 'boost/dataStore' import dataStore from 'boost/dataStore'
import keygen from 'boost/keygen' import keygen from 'boost/keygen'
@@ -43,6 +43,9 @@ let data = dataStore.getData()
let initialArticles = data.articles let initialArticles = data.articles
let initialFolders = data.folders let initialFolders = data.folders
let isStatusLocked = false
let isCreatingNew = false
function folders (state = initialFolders, action) { function folders (state = initialFolders, action) {
state = state.slice() state = state.slice()
switch (action.type) { switch (action.type) {
@@ -121,10 +124,41 @@ function folders (state = initialFolders, action) {
return state return state
} }
} }
let isCleaned = true
function articles (state = initialArticles, action) { function articles (state = initialArticles, action) {
state = state.slice() state = state.slice()
if (!isCreatingNew && !isCleaned) {
state = state.filter(article => article.status !== 'NEW')
isCleaned = true
}
switch (action.type) { switch (action.type) {
case SWITCH_ARTICLE:
if (action.data.isNew) {
isCleaned = false
}
if (!isStatusLocked && !action.data.isNew) {
isCreatingNew = false
if (!isCleaned) {
state = state.filter(article => article.status !== 'NEW')
isCleaned = true
}
}
return state
case SWITCH_FOLDER:
case SET_SEARCH_FILTER:
case SET_TAG_FILTER:
case CLEAR_SEARCH:
if (!isStatusLocked) {
isCreatingNew = false
if (!isCleaned) {
state = state.filter(article => article.status !== 'NEW')
isCleaned = true
}
}
return state
case CLEAR_NEW_ARTICLE:
return state.filter(article => article.status !== 'NEW')
case ARTICLE_UPDATE: case ARTICLE_UPDATE:
{ {
let article = action.data.article let article = action.data.article
@@ -133,7 +167,8 @@ function articles (state = initialArticles, action) {
if (targetIndex < 0) state.unshift(article) if (targetIndex < 0) state.unshift(article)
else state.splice(targetIndex, 1, article) else state.splice(targetIndex, 1, article)
dataStore.setArticles(null, state) if (article.status !== 'NEW') dataStore.setArticles(null, state)
else isCreatingNew = true
return state return state
} }
case ARTICLE_DESTROY: case ARTICLE_DESTROY:
@@ -162,16 +197,15 @@ function articles (state = initialArticles, action) {
function status (state = initialStatus, action) { function status (state = initialStatus, action) {
state = Object.assign({}, state) state = Object.assign({}, state)
switch (action.type) { switch (action.type) {
case TOGGLE_TUTORIAL: case TOGGLE_TUTORIAL:
state.isTutorialOpen = !state.isTutorialOpen state.isTutorialOpen = !state.isTutorialOpen
return state return state
case LOCK_STATUS: case LOCK_STATUS:
state.isStatusLocked = true isStatusLocked = state.isStatusLocked = true
return state return state
case UNLOCK_STATUS: case UNLOCK_STATUS:
state.isStatusLocked = false isStatusLocked = state.isStatusLocked = false
return state return state
} }
@@ -188,11 +222,10 @@ function status (state = initialStatus, action) {
return state return state
case SWITCH_MODE: case SWITCH_MODE:
state.mode = action.data state.mode = action.data
if (state.mode === CREATE_MODE) state.articleKey = null
return state return state
case SWITCH_ARTICLE: case SWITCH_ARTICLE:
state.articleKey = action.data state.articleKey = action.data.key
state.mode = IDLE_MODE state.mode = IDLE_MODE
return state return state

View File

@@ -1,6 +1,6 @@
{ {
"name": "boost", "name": "boost",
"version": "0.4.1-beta.2", "version": "0.4.1-beta.3",
"description": "Boost App", "description": "Boost App",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {