Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 61 additions & 19 deletions app/containers/userPanel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ import {
CREATE_SINGLE_GIST,
getGitHubApi,
} from '../../utilities/githubApi'
import {
clearNewGistDraft,
createNewGistDraft,
createNewGistWithDraft,
loadNewGistDraft,
} from '../../utilities/newGistDraft'

import './index.scss'

Expand All @@ -53,6 +59,25 @@ const kIsPrivate = conf.get('snippet:newSnippetPrivate')
const hideProfilePhoto = conf.get('userPanel:hideProfilePhoto')

class UserPanel extends Component {
constructor (props) {
super(props)
this.newGistInitialData = loadNewGistDraft(
electronBridge.localStorage,
this.getUserLogin(props)
) || this.createEmptyNewGistData()
}

getUserLogin (props = this.props) {
const profile = props.userSession && props.userSession.profile
return profile && profile.login
}

createEmptyNewGistData () {
return createNewGistDraft({
private: kIsPrivate
})
}

componentDidMount () {
this.ipcSubscriptions = []
subscribeIpc(ipcRenderer, this.ipcSubscriptions, 'new-gist-renderer', () => {
Expand All @@ -74,24 +99,48 @@ class UserPanel extends Component {
const isPublic = data.private === undefined ? true : !data.private
const description = data.description.trim()
const processedFiles = {}
const userLogin = this.getUserLogin()

this.newGistInitialData = createNewGistDraft(data)

data.gistFiles.forEach((file) => {
processedFiles[file.filename.trim()] = {
content: file.content
}
})

return getGitHubApi(CREATE_SINGLE_GIST)(this.props.accessToken, description, processedFiles, isPublic)
.catch((err) => {
notifyFailure(t('notification.gistCreationFailed'))
logger.error(JSON.stringify(err))
})
.then((response) => {
this.updateGistsStoreWithNewGist(response)
})
.finally(() => {
this.closeGistEditorModal()
})
return createNewGistWithDraft({
storage: electronBridge.localStorage,
userLogin,
data,
createGist: () => getGitHubApi(CREATE_SINGLE_GIST)(
this.props.accessToken,
description,
processedFiles,
isPublic
)
}).then((result) => {
if (result.status === 'failed') {
notifyFailure(
t('notification.gistCreationFailed'),
result.draftWrite && result.draftWrite.status ? t('notification.gistDraftSaved') : ''
)
logger.error(result.error && result.error.message
? result.error.message
: String(result.error))
return
}

this.updateGistsStoreWithNewGist(result.gistDetails)
this.newGistInitialData = this.createEmptyNewGistData()

const draftClear = clearNewGistDraft(electronBridge.localStorage, userLogin)
if (!draftClear || !draftClear.status) {
logger.error('Failed to clear the saved new snippet draft')
}

this.closeGistEditorModal()
})
}

updateGistsStoreWithNewGist (gistDetails) {
Expand Down Expand Up @@ -159,16 +208,9 @@ class UserPanel extends Component {
}

renderGistEditorModalBody () {
const initialData = {
description: '',
private: kIsPrivate,
gists: [
{ filename: '', content: '' }
]
}
return (
<GistEditorForm
initialData={ initialData }
initialData={ this.newGistInitialData }
formStyle={ NEW_GIST }
handleCancel = { this.closeGistEditorModal.bind(this) }
onSubmit={ this.handleCreateSingleGist.bind(this) }></GistEditorForm>
Expand Down
1 change: 1 addition & 0 deletions app/utilities/i18n/locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ module.exports = {
deletionFailed: 'Deletion failed',
gistCreated: 'Snippet created',
gistCreationFailed: 'Snippet creation failed',
gistDraftSaved: 'Your draft was saved locally. Retry when your connection returns.',
gistDeleted: 'The snippet has been deleted',
gistUpdateFailed: 'Snippet update failed',
gistUpdated: 'Snippet updated',
Expand Down
1 change: 1 addition & 0 deletions app/utilities/i18n/locales/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ module.exports = {
deletionFailed: 'No se pudo eliminar',
gistCreated: 'Snippet creado',
gistCreationFailed: 'No se pudo crear el snippet',
gistDraftSaved: 'Tu borrador se guardo localmente. Vuelve a intentarlo cuando se restablezca la conexion.',
gistDeleted: 'El snippet se elimino',
gistUpdateFailed: 'No se pudo actualizar el snippet',
gistUpdated: 'Snippet actualizado',
Expand Down
1 change: 1 addition & 0 deletions app/utilities/i18n/locales/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ module.exports = {
deletionFailed: 'Suppression echouee',
gistCreated: 'Extrait cree',
gistCreationFailed: 'Creation de l extrait echouee',
gistDraftSaved: 'Votre brouillon a ete enregistre localement. Reessayez lorsque votre connexion sera retablie.',
gistDeleted: 'L extrait a ete supprime',
gistUpdateFailed: 'Mise a jour de l extrait echouee',
gistUpdated: 'Extrait mis a jour',
Expand Down
1 change: 1 addition & 0 deletions app/utilities/i18n/locales/ja.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ module.exports = {
deletionFailed: '削除に失敗しました',
gistCreated: 'スニペットを作成しました',
gistCreationFailed: 'スニペットの作成に失敗しました',
gistDraftSaved: '下書きをローカルに保存しました。接続が復旧したら再試行してください。',
gistDeleted: 'スニペットを削除しました',
gistUpdateFailed: 'スニペットの更新に失敗しました',
gistUpdated: 'スニペットを更新しました',
Expand Down
1 change: 1 addition & 0 deletions app/utilities/i18n/locales/ko.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ module.exports = {
deletionFailed: '삭제 실패',
gistCreated: '스니펫이 생성되었습니다',
gistCreationFailed: '스니펫 생성 실패',
gistDraftSaved: '초안이 로컬에 저장되었습니다. 연결이 복구되면 다시 시도하세요.',
gistDeleted: '스니펫이 삭제되었습니다',
gistUpdateFailed: '스니펫 업데이트 실패',
gistUpdated: '스니펫이 업데이트되었습니다',
Expand Down
1 change: 1 addition & 0 deletions app/utilities/i18n/locales/tr.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ module.exports = {
deletionFailed: 'Silme başarısız',
gistCreated: 'Kod parçası oluşturuldu',
gistCreationFailed: 'Kod parçası oluşturulamadı',
gistDraftSaved: 'Taslağınız yerel olarak kaydedildi. Bağlantınız geri geldiğinde tekrar deneyin.',
gistDeleted: 'Kod parçası silindi',
gistUpdateFailed: 'Kod parçası güncellenemedi',
gistUpdated: 'Kod parçası güncellendi',
Expand Down
1 change: 1 addition & 0 deletions app/utilities/i18n/locales/zh-Hans.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ module.exports = {
deletionFailed: '删除失败',
gistCreated: '代码片段已创建',
gistCreationFailed: '代码片段创建失败',
gistDraftSaved: '草稿已保存在本地。网络恢复后请重试。',
gistDeleted: '代码片段已删除',
gistUpdateFailed: '代码片段更新失败',
gistUpdated: '代码片段已更新',
Expand Down
1 change: 1 addition & 0 deletions app/utilities/i18n/locales/zh-Hant.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ module.exports = {
deletionFailed: '刪除失敗',
gistCreated: '程式碼片段已建立',
gistCreationFailed: '程式碼片段建立失敗',
gistDraftSaved: '草稿已儲存在本機。網路恢復後請重試。',
gistDeleted: '程式碼片段已刪除',
gistUpdateFailed: '程式碼片段更新失敗',
gistUpdated: '程式碼片段已更新',
Expand Down
95 changes: 95 additions & 0 deletions app/utilities/newGistDraft.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
const NEW_GIST_DRAFT_STORAGE_PREFIX = 'new-gist-draft'

function createStorageFailure (error) {
return {
status: false,
error
}
}

export function getNewGistDraftStorageKey (userLogin) {
const owner = typeof userLogin === 'string' && userLogin.trim()
? encodeURIComponent(userLogin.trim())
: 'anonymous'

return `${NEW_GIST_DRAFT_STORAGE_PREFIX}-${owner}`
}

export function createNewGistDraft (data = {}) {
const sourceFiles = Array.isArray(data.gistFiles)
? data.gistFiles
: data.gists
const gists = Array.isArray(sourceFiles)
? sourceFiles.map(file => ({
filename: file && typeof file.filename === 'string' ? file.filename : '',
content: file && typeof file.content === 'string' ? file.content : ''
}))
: []

return {
description: typeof data.description === 'string' ? data.description : '',
private: Boolean(data.private),
gists: gists.length ? gists : [{ filename: '', content: '' }]
}
}

function isNewGistDraft (draft) {
return Boolean(
draft &&
typeof draft === 'object' &&
typeof draft.description === 'string' &&
typeof draft.private === 'boolean' &&
Array.isArray(draft.gists) &&
draft.gists.length &&
draft.gists.every(file =>
file &&
typeof file.filename === 'string' &&
typeof file.content === 'string'
)
)
}

export function loadNewGistDraft (storage, userLogin) {
try {
const result = storage.get(getNewGistDraftStorageKey(userLogin))
if (!result || !result.status || !isNewGistDraft(result.data)) return null
return createNewGistDraft(result.data)
} catch {
return null
}
}

export function saveNewGistDraft (storage, userLogin, data) {
try {
return storage.set(
getNewGistDraftStorageKey(userLogin),
createNewGistDraft(data)
)
} catch (error) {
return createStorageFailure(error)
}
}

export function createNewGistWithDraft ({ storage, userLogin, data, createGist }) {
const draftWrite = saveNewGistDraft(storage, userLogin, data)

return Promise.resolve()
.then(createGist)
.then(gistDetails => ({
status: 'created',
gistDetails,
draftWrite
}), error => ({
status: 'failed',
error,
draftWrite
}))
}

export function clearNewGistDraft (storage, userLogin) {
try {
return storage.set(getNewGistDraftStorageKey(userLogin), null)
} catch (error) {
return createStorageFailure(error)
}
}
3 changes: 3 additions & 0 deletions tests/utilities/i18n.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ describe('i18n utilities', () => {
expect(t('menu.submitGist')).toBe('Submit Snippet')
expect(t('menu.syncGist')).toBe('Sync Snippet')
expect(t('notification.gistCreated')).toBe('Snippet created')
expect(t('notification.gistDraftSaved')).toBe(
'Your draft was saved locally. Retry when your connection returns.'
)
expect(t('snippet.deleteConfirmTitle')).toBe('Delete the snippet?')
})

Expand Down
Loading