diff --git a/data/back-up.json b/data/back-up.json index e7c6e42..2e515a6 100644 --- a/data/back-up.json +++ b/data/back-up.json @@ -111,16 +111,19 @@ ], "articleId": "hp1", "partTitle": "kapitel 1", - "words": [ - { - "origWord": "Hallo", - "transWord": "Привет" + "words": { + "diemutter": { + "origText": "Mutter", + "origPrefix": "die", + "transText": "Мама", + "type": 1 }, - { - "transWord": "Привет", - "origWord": "Hallo1" + "etwasmachen": { + "origText": "etwasmachen", + "transText": "Что-то делать", + "type": 2 } - ], + }, "articlePartId": "k1", "youtubeId": "hHW1oY26kxQ", "articleTitle": "Harry Potter und Stein der Weisen - 1", @@ -139,12 +142,13 @@ ], "articleId": "hp1", "partTitle": "kapitel 2", - "words": [ - { - "transWord": "Привет", - "origWord": "Hallo2" + "words": { + "hallo": { + "origText": "Hallo", + "transText": "Привет", + "type": 1 } - ], + }, "articlePartId": "k2", "youtubeId": "hHW1oY26kxQ", "articleTitle": "Harry Potter und Stein der Weisen - 2", @@ -163,12 +167,7 @@ ], "articleId": "hp1", "partTitle": "kapitel 3", - "words": [ - { - "transWord": "Привет", - "origWord": "Hallo3" - } - ], + "words": {}, "articlePartId": "k3", "youtubeId": "hHW1oY26kxQ", "articleTitle": "Harry Potter und Stein der Weisen - 3", diff --git a/src/components/Article/Word/Card.vue b/src/components/Article/Word/Card.vue new file mode 100644 index 0000000..c38fb59 --- /dev/null +++ b/src/components/Article/Word/Card.vue @@ -0,0 +1,90 @@ + + + + + + + W + + Слово / das word + + + + RW + + Выражение / die Redewendung + + {{ getFullOriginalWord(wordEntity) }} + + + + + + + {{ wordEntity.transText }} + + + + + + add + + + warning + {{ snackbar.text }} + + + + + + diff --git a/src/components/Article/Words.vue b/src/components/Article/Words.vue index f2a55c3..12239b3 100644 --- a/src/components/Article/Words.vue +++ b/src/components/Article/Words.vue @@ -13,40 +13,43 @@ slot-scope="props" xs12 sm6 - md4 - lg3 > - - - {{ props.item.origWord }} - - - - {{ props.item.transWord }} - - - - - add - - - + - diff --git a/src/helpers/index.js b/src/helpers/index.js index ca44309..8733a98 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -1,3 +1,4 @@ export * from '@/helpers/article'; -export * from '@/helpers/utils'; export * from '@/helpers/formRules'; +export * from '@/helpers/utils'; +export * from '@/helpers/word'; diff --git a/src/helpers/word.js b/src/helpers/word.js new file mode 100644 index 0000000..cec6f28 --- /dev/null +++ b/src/helpers/word.js @@ -0,0 +1,14 @@ +export const getFullOriginalWord = (entity) => { + const { origText } = entity; + + if (entity.origPrefix) { + return `${entity.origPrefix} ${origText}`; + } + + return origText; +}; + +export const WORD_TYPES = { + WORD: 1, + REDEWNNDUNG: 2, +}; diff --git a/src/store/user.js b/src/store/user.js index 6122810..d6cd639 100644 --- a/src/store/user.js +++ b/src/store/user.js @@ -29,12 +29,12 @@ export default { } }, actions: { - signUp({ commit }, payload) { - commit('setProcessing', true); + async signUp({ commit }, payload) { + await commit('setProcessing', true); commit('clearError'); const { email, password, name } = payload; - firebase.auth() + await firebase.auth() .createUserWithEmailAndPassword(email, password) .then(() => { firebase.auth().currentUser @@ -42,29 +42,29 @@ export default { displayName: name, }) .then(() => commit('setUserName', name)); - commit('setProcessing', false); }) .catch(function(error) { const { message } = error; - commit('setProcessing', false); commit('setError', message); }); + + await commit('setProcessing', false); }, - signIn({ commit }, payload) { - commit('setProcessing', true); + async signIn({ commit }, payload) { + await commit('setProcessing', true); commit('clearError'); const { email, password } = payload; - firebase.auth() + await firebase.auth() .signInWithEmailAndPassword(email, password) .then(() => { - commit('setProcessing', false); }) .catch(function(error) { const { message } = error; - commit('setProcessing', false); commit('setError', message); }); + + await commit('setProcessing', false); }, signOut() { firebase.auth().signOut(); @@ -78,14 +78,14 @@ export default { commit('unSetUser'); } }, - changeUserProfileData({ commit }, payload) { + async changeUserProfileData({ commit }, payload) { const { email, password } = payload; const credential = firebase.auth.EmailAuthProvider.credential(email, password); - commit('setProcessing', true); + await commit('setProcessing', true); commit('clearError'); - firebase.auth().currentUser.reauthenticateAndRetrieveDataWithCredential(credential) + await firebase.auth().currentUser.reauthenticateAndRetrieveDataWithCredential(credential) .then(() => { const { changeType } = payload; const reauthenticatedUser = firebase.auth().currentUser; @@ -111,14 +111,13 @@ export default { throw Error('invalid change type'); }) - .then(() => commit('setProcessing', false)) .catch((e) => { window.console.error(e); - const { message } = e; - commit('setProcessing', false); commit('setError', message); }); + + await commit('setProcessing', false); }, }, getters: { diff --git a/src/store/userData.js b/src/store/userData.js index f44b301..4627321 100644 --- a/src/store/userData.js +++ b/src/store/userData.js @@ -10,11 +10,11 @@ export default { userData: defaultUserData, }, actions: { - loadUserData({ commit }, userId) { - commit('setProcessing', true); + async loadUserData({ commit }, userId) { + await commit('setProcessing', true); let userDataRef = Vue.$db.collection('userData').doc(userId); - userDataRef.get() + await userDataRef.get() .then((data) => { let userData = data.exists ? data.data() : defaultUserData; @@ -22,14 +22,18 @@ export default { userData.articles = {}; } + if (!userData.words) { + userData.words = {}; + } + commit('setUserData', userData); }) .catch(e => window.console.error(e)); - commit('setProcessing', false); + await commit('setProcessing', false); }, - addUserArticle({ commit, getters }, articleId) { - commit('setProcessing', true); + async addUserArticle({ commit, getters }, articleId) { + await commit('setProcessing', true); const userDataRef = Vue.$db.collection('userData').doc(getters.userId); const article = { @@ -37,7 +41,7 @@ export default { parts: {}, }; - userDataRef.set({ + await userDataRef.set({ articles: { [articleId]: article, } @@ -45,7 +49,45 @@ export default { .then(() => commit('addUserArticle', { articleId, article })) .catch(e => window.console.error(e)); - commit('setProcessing', false); + await commit('setProcessing', false); + }, + async addUserWord({ commit, getters }, wordEntity) { + await commit('setProcessing', true); + + const { key, ...wordEntityData } = wordEntity; + + const userDataRef = Vue.$db.collection('userData').doc(getters.userId); + const word = Object.assign({}, wordEntityData, { + addedAt: new Date(), + // about this {@see https://en.wikipedia.org/wiki/Leitner_system} + bucket: 1, + nextShowDate: new Date(), + }); + + await userDataRef.set({ + words: { + [key]: word, + } + }, { merge: true }) + .then(() => commit('addUserWord', { wordKey: key, word })) + .catch(e => window.console.error(e)); + + await commit('setProcessing', false); + }, + async finishUserArticlePart({ commit, getters }, { articleId, partId, rating }) { + await commit('setProcessing', true); + + const userDataRef = Vue.$db.collection('userData').doc(getters.userId); + const timestamp = new Date(); + + await userDataRef.update({ + [`articles.${articleId}.parts.${partId}.finishedAt`]: timestamp, + [`articles.${articleId}.parts.${partId}.rating`]: rating, + }) + .then(() => commit('finishUserArticlePart', { articleId, partId, timestamp, rating })) + .catch(e => window.console.error(e)); + + await commit('setProcessing', false); }, updateUserArticlePartStats({ commit, getters }, { articleId, partId }) { const userDataRef = Vue.$db.collection('userData').doc(getters.userId); @@ -66,21 +108,6 @@ export default { .then(() => commit('openUserArticlePart', { articleId, partId, timestamp })) .catch(e => window.console.error(e)); }, - finishUserArticlePart({ commit, getters }, { articleId, partId, rating }) { - commit('setProcessing', true); - - const userDataRef = Vue.$db.collection('userData').doc(getters.userId); - const timestamp = new Date(); - - userDataRef.update({ - [`articles.${articleId}.parts.${partId}.finishedAt`]: timestamp, - [`articles.${articleId}.parts.${partId}.rating`]: rating, - }) - .then(() => commit('finishUserArticlePart', { articleId, partId, timestamp, rating })) - .catch(e => window.console.error(e)); - - commit('setProcessing', false); - } }, mutations: { setUserData(state, payload) { @@ -97,6 +124,9 @@ export default { Vue.set(state.userData.articles[articleId].parts, partId, { addedAt: timestamp }); }, + addUserWord(state, { wordKey, word }) { + Vue.set(state.userData.words, wordKey, word); + }, openUserArticlePart(state, { articleId, partId, timestamp }) { Vue.set(state.userData.articles[articleId].parts[partId], 'lastOpenedAt', timestamp); }, diff --git a/src/views/ArticlePart.vue b/src/views/ArticlePart.vue index 72963a0..6b51caa 100644 --- a/src/views/ArticlePart.vue +++ b/src/views/ArticlePart.vue @@ -21,7 +21,7 @@ - + @@ -105,7 +105,7 @@ storedRating() { const articlePart = this.currentUserArticlePart; return articlePart ? articlePart.rating : 0; - } + }, }, methods: { finishWork() {