From 45c627b0a5e1b72e29886f622101f422761a1227 Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Tue, 3 May 2016 15:37:14 +0900 Subject: [PATCH] using Repository class --- browser/lib/RepositoryManager.js | 312 ------------------ .../{Repository.js => RepositorySection.js} | 23 +- ...Repository.styl => RepositorySection.styl} | 0 browser/main/HomePage/SideNav/index.js | 20 +- browser/main/HomePage/index.js | 243 +++----------- browser/main/actions.js | 200 ----------- browser/main/modal/NewRepositoryModal.js | 42 ++- browser/main/store.js | 58 +++- 8 files changed, 151 insertions(+), 747 deletions(-) delete mode 100644 browser/lib/RepositoryManager.js rename browser/main/HomePage/SideNav/{Repository.js => RepositorySection.js} (80%) rename browser/main/HomePage/SideNav/{Repository.styl => RepositorySection.styl} (100%) delete mode 100644 browser/main/actions.js diff --git a/browser/lib/RepositoryManager.js b/browser/lib/RepositoryManager.js deleted file mode 100644 index 1c1f3a1a..00000000 --- a/browser/lib/RepositoryManager.js +++ /dev/null @@ -1,312 +0,0 @@ -const keygen = require('browser/lib/keygen') -const fs = require('fs') -const path = require('path') -const CSON = require('season') -const _ = require('lodash') - -/** - * # Repo structure - * - * ``` - * root - * |- data - * |-note1.cson - * |-note2.cson - * |-note3.cson - * |- boostrepo.json - * ``` - * - * ## `boostrepo.json` - * - * ```js - * { - * name: String, - * author: String, // Same convention of package.json, `John Doe (http://example.com)` - * remotes: [{ - * name: String, - * url: String, // url of git remote - * branch: String // if branch isn't set, it will try to use `master` branch. - * }], - * folders: [{ - * key: String // Unique sha1 hash key to identify folder, - * name: String, - * color: String // All CSS color formats available. - * }] - * } - * ``` - * - * ## `data` directory - * - * Every note will be saved here as a single CSON file to `git diff` efficiently. - * > This is because CSON supports Multiline string. - * File name of each cson file will be used to identify note. - * Commonly, Boostnote will automatically generate sha1 key and use it as a file name when creating a new note. - * - * ### `note.cson` - * - * ```cson - * name: String - * tags: [String] // tags - * folder: String // hash key of folder - * mode: String // syntax mode - * title: String - * content: String - * createdAt: Date - * updatedAt: Date - * ``` - */ - -/** - * # Resolve directory. - * - * If directory doesn't exist, it will try to make a new one. - * If failed return rejected promise - * - * @param {String} targetPath Target path of directory - * @return {Promise} [description] - */ -function _resolveDirectory (targetPath) { - return new Promise(function (resolve, reject) { - // check the directory exists - fs.stat(targetPath, function (err, stat) { - // Reject errors except no suchfile - if (err != null && err.code !== 'ENOENT') { - return reject(err) - } - - // Handle no suchfile error only - // Make new Folder by given path - if (err != null) { - return fs.mkdir(targetPath, function (err, stat) { - // If failed to make a new directory, reject it. - if (err != null) { - return reject(err) - } - resolve(targetPath) - }) - } - - // Check the target is not a directory - if (!stat.isDirectory()) { - return reject(new Error(targetPath + ' path is not a directory')) - } - resolve(targetPath) - }) - }) -} - -function _generateDefaultRepoJSON (override) { - return Object.assign({ - name: 'default', - remotes: [], - folders: [{ - key: keygen(), - name: 'general', - color: 'green' - }] - }, override) -} - -/** - * # Resolve RepoJSON - * - * Every repository must have `boostrepo.json` - * - * If boostrepo.json doesn't exist, create new one. - * - * @param {[type]} targetPath [description] - * @return {[type]} [description] - */ -function _resolveRepoJSON (targetPath) { - return new Promise(function checkIfExists (resolve, reject) { - // If JSON doesn't exist, make a new one. - if (CSON.resolve(targetPath) == null) { - let newRepoJSON = _generateDefaultRepoJSON() - return CSON.writeFile(targetPath, newRepoJSON, function (err) { - if (err != null) return reject(err) - resolve(newRepoJSON) - }) - } - - CSON.readFile(targetPath, function (err, obj) { - if (err != null) return reject(err) - resolve(obj) - }) - }) -} - -/** - * Get all repository stats from localStorage - * it is stored to `repositories` key. - * if the data is corrupted, re-intialize it. - * - * @return {Array} registered repositories - * ``` - * [{ - * key: String, - * name: String, - * path: String // path of repository - * }] - * ``` - */ -function getAllRepoStats () { - let data - try { - data = JSON.parse(localStorage.getItem('repoStats')) - if (!_.isArray(data)) { - throw new Error('Data is corrupted. it must be an array.') - } - } catch (err) { - console.log(err) - data = [] - _saveAllRepoStats(data) - } - return data -} - -/** - * Save All Repos - */ -function _saveAllRepoStats (repoStats) { - localStorage.setItem('repoStats', JSON.stringify(repoStats)) -} - -/** - * Add repository and return new Repo - * @param {Object} newRepo [description] - * ``` - * { - * key: String, - * name: String, - * path: String, - * status: String, - * folders: [{ - * key: String, - * color: String, - * name: String - * }], - * notes: [{ - * key: String, - * title: String, - * content: String, - * folder: String, - * tags: [String], - * createdAt: Date, - * updatedAt: Date - * }] - * } - * ``` - */ -function addRepo (newRepo) { - let { targetPath, name } = newRepo - targetPath = path.resolve(targetPath) - - let repoStat, repoJSON - return _resolveDirectory(targetPath) - .then(function initializeRepo () { - let resolveDataDirectory = _resolveDirectory(path.resolve(targetPath, 'data')) - let resolveBoostrepoJSON = _resolveRepoJSON(path.resolve(targetPath, 'boostrepo.json')) - return Promise.all([resolveDataDirectory, resolveBoostrepoJSON]) - }) - .then(function saveToLocalStorage (data) { - let dataPath = data[0] - repoJSON = data[1] - - let repoStats = getAllRepoStats() - - // generate unique key - let key = keygen() - while (repoStats.some((repoStat) => repoStat.key === key)) { - key = keygen() - } - - repoStat = { - key, - name: name, - path: targetPath - } - - repoStats.push(repoStat) - _saveAllRepoStats(repoStats) - - return dataPath - }) - .then(function fetchNotes (dataPath) { - let noteNames = fs.readdirSync(dataPath) - let notes = noteNames - .map((noteName) => { - let notePath = path.resolve(dataPath, noteNames) - - return new Promise(function (resolve, reject) { - CSON.readFile(notePath, function (err, obj) { - if (err != null) { - console.log(err) - return resolve(null) - } - obj.key = path.basename(noteName, '.cson') - return resolve(obj) - }) - }) - }) - .filter((note) => note != null) - - return Promise.all(notes) - }) - .then(function resolveRepo (notes) { - return Object.assign({}, repoJSON, repoStat, { - status: 'IDLE', - notes - }) - }) -} - -function removeRepo (repository) { - return new Promise(function (resolve, reject) { - try { - let repoStats = getAllRepoStats() - let targetIndex = _.findIndex(repoStats, {key: repository.key}) - if (targetIndex > -1) { - repoStats.splice(targetIndex, 1) - } - _saveAllRepoStats(repoStats) - resolve(true) - } catch (err) { - reject(err) - } - }) -} - -function getRepos () { - let repoStats - try { - repoStats = JSON.parse(localStorage.getItem('repoStats')) - if (repoStats == null) repoStats = [] - } catch (err) { - repoStats = [] - } - return repoStats - .map((repoStat) => { - let repoJSON, notes - try { - repoJSON = CSON.readFileSync(path.resolve(repoStat.path, 'boostrepo.json')) - let notePaths = fs.readdirSync(path.resolve(repoStat.path, 'data')) - notes = notePaths.map((notePath) => CSON.readFileSync(notePath)) - } catch (err) { - return Object.assign({}, repoStat, { - status: 'ERROR', - error: err - }) - } - return Object.assign({}, repoJSON, repoStat, { - status: 'IDLE', - notes - }) - }) -} - -export default { - getAllRepoStats, - addRepo, - removeRepo, - getRepos -} diff --git a/browser/main/HomePage/SideNav/Repository.js b/browser/main/HomePage/SideNav/RepositorySection.js similarity index 80% rename from browser/main/HomePage/SideNav/Repository.js rename to browser/main/HomePage/SideNav/RepositorySection.js index 4631af6b..e0ccc29c 100644 --- a/browser/main/HomePage/SideNav/Repository.js +++ b/browser/main/HomePage/SideNav/RepositorySection.js @@ -1,16 +1,21 @@ import React, { PropTypes } from 'react' import CSSModules from 'browser/lib/CSSModules' -import styles from './Repository.styl' -import actions from 'browser/main/actions' -import RepositoryManager from 'browser/lib/RepositoryManager' +import styles from './RepositorySection.styl' +import Repository from 'browser/lib/Repository' -class Repository extends React.Component { +class RepositorySection extends React.Component { handleUnlinkButtonClick (e) { let { dispatch, repository } = this.props - RepositoryManager.removeRepo(repository) + Repository.find(repository.key) + .then((repositoryInstance) => { + return repositoryInstance.unmount() + }) .then(() => { - dispatch(actions.removeRepo(repository)) + dispatch({ + type: 'REMOVE_REPOSITORY', + key: repository.key + }) }) } @@ -40,7 +45,7 @@ class Repository extends React.Component { return (
@@ -76,7 +81,7 @@ class Repository extends React.Component { } } -Repository.propTypes = { +RepositorySection.propTypes = { repository: PropTypes.shape({ name: PropTypes.string, folders: PropTypes.arrayOf(PropTypes.shape({ @@ -86,4 +91,4 @@ Repository.propTypes = { dispatch: PropTypes.func } -export default CSSModules(Repository, styles) +export default CSSModules(RepositorySection, styles) diff --git a/browser/main/HomePage/SideNav/Repository.styl b/browser/main/HomePage/SideNav/RepositorySection.styl similarity index 100% rename from browser/main/HomePage/SideNav/Repository.styl rename to browser/main/HomePage/SideNav/RepositorySection.styl diff --git a/browser/main/HomePage/SideNav/index.js b/browser/main/HomePage/SideNav/index.js index be606bdd..3d26e1df 100644 --- a/browser/main/HomePage/SideNav/index.js +++ b/browser/main/HomePage/SideNav/index.js @@ -1,11 +1,10 @@ import React, { PropTypes } from 'react' import CSSModules from 'browser/lib/CSSModules' import styles from './SideNav.styl' -import actions from 'browser/main/actions' import { openModal, isModalOpen } from 'browser/lib/modal' import Preferences from '../../modal/Preferences' import CreateNewFolder from '../../modal/CreateNewFolder' -import Repository from './Repository' +import RepositorySection from './RepositorySection' import NewRepositoryModal from '../../modal/NewRepositoryModal' const ipc = require('electron').ipcRenderer @@ -39,13 +38,11 @@ class SideNav extends React.Component { handleFolderButtonClick (name) { return (e) => { let { dispatch } = this.props - dispatch(actions.switchFolder(name)) } } handleAllFoldersButtonClick (e) { let { dispatch } = this.props - dispatch(actions.setSearchFilter('')) } handleNewRepositoryButtonClick (e) { @@ -55,8 +52,8 @@ class SideNav extends React.Component { render () { let { repositories, dispatch } = this.props let repositorieElements = repositories.map((repo) => { - return @@ -108,17 +105,6 @@ class SideNav extends React.Component { SideNav.propTypes = { dispatch: PropTypes.func, - status: PropTypes.shape({ - folderId: PropTypes.number - }), - user: PropTypes.object, - folders: PropTypes.array, - allArticles: PropTypes.array, - articles: PropTypes.array, - modified: PropTypes.array, - activeArticle: PropTypes.shape({ - key: PropTypes.string - }), repositories: PropTypes.array } diff --git a/browser/main/HomePage/index.js b/browser/main/HomePage/index.js index da4c3dfa..93e06316 100644 --- a/browser/main/HomePage/index.js +++ b/browser/main/HomePage/index.js @@ -1,30 +1,31 @@ import React, { PropTypes} from 'react' import { connect } from 'react-redux' import ReactDOM from 'react-dom' -import { toggleTutorial } from '../actions' import SideNav from './SideNav' import ArticleTopBar from './ArticleTopBar' import ArticleList from './ArticleList' import ArticleDetail from './ArticleDetail' -import _ from 'lodash' import { isModalOpen, closeModal } from 'browser/lib/modal' +import Repository from 'browser/lib/Repository' const electron = require('electron') const remote = electron.remote -const TEXT_FILTER = 'TEXT_FILTER' -const FOLDER_FILTER = 'FOLDER_FILTER' -const FOLDER_EXACT_FILTER = 'FOLDER_EXACT_FILTER' -const TAG_FILTER = 'TAG_FILTER' - const OSX = global.process.platform === 'darwin' class HomePage extends React.Component { componentDidMount () { - // React自体のKey入力はfocusされていないElementからは動かないため、 - // `window`に直接かける - this.keyHandler = e => this.handleKeyDown(e) - window.addEventListener('keydown', this.keyHandler) + let { dispatch } = this.props + + // Bind directly to window + // this.keyHandler = (e) => this.handleKeyDown(e) + // window.addEventListener('keydown', this.keyHandler) + + // Reload all data + Repository.loadAll() + .then((allData) => { + dispatch({type: 'INIT_ALL', data: allData}) + }) } componentWillUnmount () { @@ -32,216 +33,72 @@ class HomePage extends React.Component { } handleKeyDown (e) { - if (isModalOpen()) { - if (e.keyCode === 13 && (OSX ? e.metaKey : e.ctrlKey)) { - remote.getCurrentWebContents().send('modal-confirm') - } - if (e.keyCode === 27) closeModal() - return - } + // if (isModalOpen()) { + // if (e.keyCode === 13 && (OSX ? e.metaKey : e.ctrlKey)) { + // remote.getCurrentWebContents().send('modal-confirm') + // } + // if (e.keyCode === 27) closeModal() + // return + // } - let { status, dispatch } = this.props - let { top, list } = this.refs - let listElement = ReactDOM.findDOMNode(list) + // let { dispatch } = this.props + // let { top, list } = this.refs + // let listElement = ReactDOM.findDOMNode(list) - if (status.isTutorialOpen) { - dispatch(toggleTutorial()) - e.preventDefault() - return - } + // if (status.isTutorialOpen) { + // // dispatch(toggleTutorial()) + // e.preventDefault() + // return + // } - if (e.keyCode === 13 && top.isInputFocused()) { - listElement.focus() - return - } - if (e.keyCode === 27 && top.isInputFocused()) { - if (status.search.length > 0) top.escape() - else listElement.focus() - return - } + // if (e.keyCode === 13 && top.isInputFocused()) { + // listElement.focus() + // return + // } + // if (e.keyCode === 27 && top.isInputFocused()) { + // // if (status.search.length > 0) top.escape() + // // else listElement.focus() + // return + // } - // Search inputがfocusされていたら大体のキー入力は無視される。 - if (e.keyCode === 27) { - if (document.activeElement !== listElement) { - listElement.focus() - } else { - top.focusInput() - } - return - } + // // Search inputがfocusされていたら大体のキー入力は無視される。 + // if (e.keyCode === 27) { + // if (document.activeElement !== listElement) { + // listElement.focus() + // } else { + // top.focusInput() + // } + // return + // } } render () { - let { dispatch, status, user, articles, allArticles, modified, activeArticle, folders, tags } = this.props - let { repositories } = this.props - return (
) } } -// Ignore invalid key -function ignoreInvalidKey (key) { - return key.length > 0 && !key.match(/^\/\/$/) && !key.match(/^\/$/) && !key.match(/^#$/) && !key.match(/^--/) -} - -// Build filter object by key -function buildFilter (key) { - if (key.match(/^\/\/.+/)) { - return {type: FOLDER_EXACT_FILTER, value: key.match(/^\/\/(.+)$/)[1]} - } - if (key.match(/^\/.+/)) { - return {type: FOLDER_FILTER, value: key.match(/^\/(.+)$/)[1]} - } - if (key.match(/^#(.+)/)) { - return {type: TAG_FILTER, value: key.match(/^#(.+)$/)[1]} - } - return {type: TEXT_FILTER, value: key} -} - -function isContaining (target, needle) { - return target.match(new RegExp(_.escapeRegExp(needle), 'i')) -} - -function startsWith (target, needle) { - return target.match(new RegExp('^' + _.escapeRegExp(needle), 'i')) -} - -function remap (state) { - let { user, folders, status } = state - let _articles = state.articles - - let articles = _articles != null ? _articles.data : [] - let modified = _articles != null ? _articles.modified : [] - - articles.sort((a, b) => { - let match = new Date(b.updatedAt) - new Date(a.updatedAt) - if (match === 0) match = b.title.localeCompare(a.title) - if (match === 0) match = b.key.localeCompare(a.key) - return match - }) - let allArticles = articles.slice() - - let tags = _.uniq(allArticles.reduce((sum, article) => { - if (!_.isArray(article.tags)) return sum - return sum.concat(article.tags) - }, [])) - - if (status.search.split(' ').some(key => key === '--unsaved')) articles = articles.filter(article => _.findWhere(modified, {key: article.key})) - // Filter articles - let filters = status.search.split(' ') - .map(key => key.trim()) - .filter(ignoreInvalidKey) - .map(buildFilter) - - let folderExactFilters = filters.filter(filter => filter.type === FOLDER_EXACT_FILTER) - let folderFilters = filters.filter(filter => filter.type === FOLDER_FILTER) - let textFilters = filters.filter(filter => filter.type === TEXT_FILTER) - let tagFilters = filters.filter(filter => filter.type === TAG_FILTER) - - let targetFolders - if (folders != null) { - let exactTargetFolders = folders.filter(folder => { - return _.find(folderExactFilters, filter => filter.value.toLowerCase() === folder.name.toLowerCase()) - }) - let fuzzyTargetFolders = folders.filter(folder => { - return _.find(folderFilters, filter => startsWith(folder.name.replace(/_/g, ''), filter.value.replace(/_/g, ''))) - }) - targetFolders = status.targetFolders = exactTargetFolders.concat(fuzzyTargetFolders) - - if (targetFolders.length > 0) { - articles = articles.filter(article => { - return _.findWhere(targetFolders, {key: article.FolderKey}) - }) - } - - if (textFilters.length > 0) { - articles = textFilters.reduce((articles, textFilter) => { - return articles.filter(article => { - return isContaining(article.title, textFilter.value) || isContaining(article.content, textFilter.value) - }) - }, articles) - } - - if (tagFilters.length > 0) { - articles = tagFilters.reduce((articles, tagFilter) => { - return articles.filter(article => { - return _.find(article.tags, tag => isContaining(tag, tagFilter.value)) - }) - }, articles) - } - } - - // Grab active article - let activeArticle = _.findWhere(articles, {key: status.articleKey}) - if (activeArticle == null) activeArticle = articles[0] - - let { repositories } = state - - return { - user, - folders, - status, - articles, - allArticles, - modified, - activeArticle, - tags, - repositories - } -} - HomePage.propTypes = { - status: PropTypes.shape(), - user: PropTypes.shape({ - name: PropTypes.string - }), - articles: PropTypes.array, - allArticles: PropTypes.array, - modified: PropTypes.array, - activeArticle: PropTypes.shape(), dispatch: PropTypes.func, - folders: PropTypes.array, - tags: PropTypes.array, repositories: PropTypes.array } -export default connect(remap)(HomePage) +export default connect((x) => x)(HomePage) diff --git a/browser/main/actions.js b/browser/main/actions.js deleted file mode 100644 index da3e4b42..00000000 --- a/browser/main/actions.js +++ /dev/null @@ -1,200 +0,0 @@ -// Action types -export const USER_UPDATE = 'USER_UPDATE' - -export const ARTICLE_UPDATE = 'ARTICLE_UPDATE' -export const ARTICLE_DESTROY = 'ARTICLE_DESTROY' -export const ARTICLE_SAVE = 'ARTICLE_SAVE' -export const ARTICLE_SAVE_ALL = 'ARTICLE_SAVE_ALL' -export const ARTICLE_CACHE = 'ARTICLE_CACHE' -export const ARTICLE_UNCACHE = 'ARTICLE_UNCACHE' -export const ARTICLE_UNCACHE_ALL = 'ARTICLE_UNCACHE_ALL' - -export const FOLDER_CREATE = 'FOLDER_CREATE' -export const FOLDER_UPDATE = 'FOLDER_UPDATE' -export const FOLDER_DESTROY = 'FOLDER_DESTROY' -export const FOLDER_REPLACE = 'FOLDER_REPLACE' - -export const SWITCH_FOLDER = 'SWITCH_FOLDER' -export const SWITCH_ARTICLE = 'SWITCH_ARTICLE' -export const SET_SEARCH_FILTER = 'SET_SEARCH_FILTER' -export const SET_TAG_FILTER = 'SET_TAG_FILTER' -export const CLEAR_SEARCH = 'CLEAR_SEARCH' - -export const TOGGLE_TUTORIAL = 'TOGGLE_TUTORIAL' - -// Article status -export const NEW = 'NEW' - -export function updateUser (input) { - return { - type: USER_UPDATE, - data: input - } -} - -// DB -export function cacheArticle (key, article) { - return { - type: ARTICLE_CACHE, - data: { key, article } - } -} - -export function uncacheArticle (key) { - return { - type: ARTICLE_UNCACHE, - data: { key } - } -} - -export function uncacheAllArticles () { - return { - type: ARTICLE_UNCACHE_ALL - } -} - -export function saveArticle (key, article, forceSwitch) { - return { - type: ARTICLE_SAVE, - data: { key, article, forceSwitch } - } -} - -export function saveAllArticles () { - return { - type: ARTICLE_SAVE_ALL - } -} - -export function updateArticle (article) { - return { - type: ARTICLE_UPDATE, - data: { article } - } -} - -export function destroyArticle (key) { - return { - type: ARTICLE_DESTROY, - data: { key } - } -} - -export function createFolder (folder) { - return { - type: FOLDER_CREATE, - data: { folder } - } -} - -export function updateFolder (folder) { - return { - type: FOLDER_UPDATE, - data: { folder } - } -} - -export function destroyFolder (key) { - return { - type: FOLDER_DESTROY, - data: { key } - } -} - -export function replaceFolder (a, b) { - return { - type: FOLDER_REPLACE, - data: { - a, - b - } - } -} - -export function switchFolder (folderName) { - return { - type: SWITCH_FOLDER, - data: folderName - } -} - -export function switchArticle (articleKey) { - return { - type: SWITCH_ARTICLE, - data: { - key: articleKey - } - } -} - -export function setSearchFilter (search) { - return { - type: SET_SEARCH_FILTER, - data: search - } -} - -export function setTagFilter (tag) { - return { - type: SET_TAG_FILTER, - data: tag - } -} - -export function clearSearch () { - return { - type: CLEAR_SEARCH - } -} - -export function toggleTutorial () { - return { - type: TOGGLE_TUTORIAL - } -} - -/** - * v0.6.* Actions - */ - -export function addRepo (data) { - return { - type: 'ADD_REPOSITORY', - data - } -} - -export function removeRepo (data) { - return { - type: 'REMOVE_REPOSITORY', - data - } -} - -export default { - updateUser, - - updateArticle, - destroyArticle, - cacheArticle, - uncacheArticle, - uncacheAllArticles, - saveArticle, - saveAllArticles, - - createFolder, - updateFolder, - destroyFolder, - replaceFolder, - - switchFolder, - switchArticle, - setSearchFilter, - setTagFilter, - clearSearch, - toggleTutorial, - - // v0.6.* - addRepo, - removeRepo -} diff --git a/browser/main/modal/NewRepositoryModal.js b/browser/main/modal/NewRepositoryModal.js index 600b0fd6..c1433e5f 100644 --- a/browser/main/modal/NewRepositoryModal.js +++ b/browser/main/modal/NewRepositoryModal.js @@ -1,10 +1,8 @@ import React, { PropTypes } from 'react' import CSSModules from 'browser/lib/CSSModules' import styles from './NewRepositoryModal.styl' -import linkState from 'browser/lib/linkState' -import RepositoryManager from 'browser/lib/RepositoryManager' +import Repository from 'browser/lib/Repository' import store from 'browser/main/store' -import actions from 'browser/main/actions' const electron = require('electron') const remote = electron.remote @@ -81,13 +79,19 @@ class NewRepositoryModal extends React.Component { let targetPath = this.state.path let name = this.state.name - RepositoryManager - .addRepo({ - targetPath, - name - }) - .then((newRepo) => { - store.dispatch(actions.addRepo(newRepo)) + let repository = new Repository({ + name: name, + path: targetPath + }) + + repository + .mount() + .then(() => repository.load()) + .then((data) => { + store.dispatch({ + type: 'ADD_REPOSITORY', + repository: data + }) this.props.close() }) .catch((err) => { @@ -98,6 +102,15 @@ class NewRepositoryModal extends React.Component { }) } + handleChange (e) { + let name = this.refs.nameInput.value + let path = this.refs.pathInput.value + this.setState({ + name, + path + }) + } + render () { return (
Repository Name
this.handleChange(e)} />
@@ -124,11 +138,13 @@ class NewRepositoryModal extends React.Component {
Repository Path
this.handlePathFocus(e)} onBlur={(e) => this.handlePathBlur(e)} disabled={this.state.isBrowsingPath} + onChange={(e) => this.handleChange(e)} />