From 7471e58aa9a66d10b7c48407b308673898e7d1a9 Mon Sep 17 00:00:00 2001 From: horhik Date: Sun, 8 Mar 2020 03:18:34 -0400 Subject: [PATCH] add anki Model creator --- src/actions/anki-get-actions.js | 24 ++- src/actions/createAnkiLanModel.js | 205 +++++++++++++++++++++- src/components/add-word-form.jsx | 4 +- src/components/view/add-main-template.jsx | 8 +- src/components/view/deck-picker.jsx | 12 +- src/reducers/anki-reducer.js | 17 +- 6 files changed, 241 insertions(+), 29 deletions(-) diff --git a/src/actions/anki-get-actions.js b/src/actions/anki-get-actions.js index 4036b23..3aeeb8b 100644 --- a/src/actions/anki-get-actions.js +++ b/src/actions/anki-get-actions.js @@ -60,11 +60,20 @@ export const getDeckList = () => async dispatch => { } }; -export const getModelList = async ( - getModelListFunction = AnkiDroid.getModelList, -) => { - const [err, res] = await getModelListFunction(); - return err ? {type: ERROR, err} : {type: GET_MODEL_LIST, payload: res}; +const setModelList = res => { + return {type: GET_MODEL_LIST, payload: res}; +}; +export const getModelList = () => async dispatch => { + try { + const [err, res] = await AnkiDroid.getModelList(); + if (err) { + throw err; + } + console.log(res); + await dispatch(setModelList(res)); + } catch (err) { + console.log(err); + } }; export const getFieldList = async ( @@ -82,9 +91,9 @@ const setExistingOfAnkiLanModel = existing => { payload: existing, }; }; -export const checkAnkiLanModelForExisting = id => async dispatch => { +export const checkAnkiLanModelForExisting = name => async dispatch => { try { - const [err, res] = await AnkiDroid.getFieldList('', id); + const [err, res] = await AnkiDroid.getFieldList(name); if (err) { throw err; } @@ -94,6 +103,5 @@ export const checkAnkiLanModelForExisting = id => async dispatch => { } catch (err) { await dispatch(setExistingOfAnkiLanModel(false)); await createAnkiLanModel(id); - console.log('errrororo', err); } }; diff --git a/src/actions/createAnkiLanModel.js b/src/actions/createAnkiLanModel.js index d8bd678..cfc7a4f 100644 --- a/src/actions/createAnkiLanModel.js +++ b/src/actions/createAnkiLanModel.js @@ -1,6 +1,13 @@ import {AnkiDroid} from 'react-native-ankidroid/dist/ankidroid'; export const createAnkiLanModel = model => async dispatch => { + try { + /* + (async function() { + const [err, res] = await AnkiDroid.getSelectedDeckName(); + console.log(model.deck); + console.log(typeof res); + })(); try { const modelFields = [ 'Word or sentence', @@ -15,8 +22,8 @@ export const createAnkiLanModel = model => async dispatch => { 'Sound', ]; - const css = ``; const answerFormat = ` @@ -38,7 +45,7 @@ export const createAnkiLanModel = model => async dispatch => {
  1. -
    {{Translate 1}}
    +
    {{Translate 1}}
    Qq
    {{Definition 1}}
  2. @@ -77,10 +84,9 @@ export const createAnkiLanModel = model => async dispatch => { const settings = { modelId: model.id, modelProperties, - deckId: '1582019808117', + deckId: model.deck.id, }; - const currentDeck = new AnkiDroid(settings); - currentDeck.addNote( + new AnkiDroid(settings).addNote( [ 'Word or sentence', 'Part of speech 1', @@ -97,5 +103,190 @@ export const createAnkiLanModel = model => async dispatch => { ); } catch (err) { console.log(err); + }*/ + + /////////////////////////////////// + // SETTING UP THE DECK AND MODEL // + /////////////////////////////////// + + // Name of deck which will be created in AnkiDroid + const deckName = model.deck.name; + // Name of model which will be created in AnkiDroid (can be any string) + const modelName = model.name + '_test'; + // Used to save a reference to this deck in the SharedPreferences (can be any string) + const dbDeckReference = 'com.anki.decks'; + // Used to save a reference to this model in the SharedPreferences (can be any string) + const dbModelReference = 'com.anki.models'; + // Optional space separated list of tags to add to every note + const tags = ['AnkiLan']; + // List of field names that will be used in AnkiDroid model + const modelFields = [ + 'Word or sentence', + 'Part of speech 1', + 'Translation 1', + 'Definition 1', + 'Part of speech 2', + 'Translation 2', + 'Definition 2', + 'Usage example', + 'Transcription', + 'Sound', + ]; + // List of card names that will be used in AnkiDroid (one for each direction of learning) + const cardNames = ['Russian>English', 'English>Russian']; + // CSS to share between all the cards (optional). + const css = `.card { + font-family: 'Roboto', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; + font-size: 24px; + text-align: center; + color: black; + background-color: white; + word-wrap: break-word; + } + + .big { + font-size: 48px; + } + + .small { + font-size: 18px; + } + + .sound--container { + display: flex; + justify-content: center; + padding: 0px; + align-items: center; + } + + .sound { + padding-left: 10px; + } + + .transcription { + color: #1e7efc; + font-weight: bold; + } +.list{ +list-style: none; +display: flex; +flex-direction:column; +align-items:center; +padding: 0; +} +.definition{ +font-size: 20px; +font-famyli: sans-serif; +font-style: italic; +display: block; +margin: 7px ; +padding: 0 20px ; +white-space: normal; +width: 70vw; +} +.usage{ +background-color: rgba(100,100,100,0.1); +padding: 10px; +font-size: 20px; +white-space: normal; +width: 70vw; +margin: 0 auto; +border-radius: 5px; +}`; + // Template for the question of each card + const questionFmt1 = ` +
    {{Word or sentence}}
    + +
    +
    {{Transcription}}
    + {{Sound}} + `; + const questionFmt2 = '
    {{Translation 1}}
    '; + const questionFormat = [questionFmt1, questionFmt2]; + // Template for the answer (this example is identical for both sides) + const answerFmt1 = ` +
    {{Word or sentence}}
    +
    +
    {{Transcription}}
    + {{Sound}} +
    + + +
    + +
    {{Usage example}}
    + +
    +
      +
    • +
      +
      {{Part of speech 1}}
      +
      {{Definition 1}}
      +
      {{Translation 1}}
      +
      +
    • +
    • +
      +
      {{Part of speech 2}}
      +
      {{Definition 2}}
      +
      {{Translation 2}}
      +
      +
    • +
    +
    `; + const answerFormat = [answerFmt1, answerFmt1]; + + ////////////////// + // ADDING NOTES // + ////////////////// + + const deckProperties = { + name: deckName, + reference: dbDeckReference, + }; + const modelProperties = { + name: modelName, + reference: dbModelReference, + fields: modelFields, + tags, + cardNames, + questionFormat, + answerFormat, + css, + }; + + const valueFields = [ + 'Word or sentence', + 'Part of speech 1', + 'Translation 1', + 'Definition 1', + 'Part of speech 2', + 'Translation 2', + 'Definition 2', + 'Usage example', + 'Transcription', + 'Sound', + ]; + + const settings = { + modelId: undefined, + modelProperties: modelProperties, + deckId: model.deck.id, + deckProperties: deckProperties, + }; + + const selectedDeck = new AnkiDroid(settings); + + selectedDeck.addNote(valueFields, modelFields); + // returns a promise that returns the added note ID + } catch (err) { + console.log(err); } }; diff --git a/src/components/add-word-form.jsx b/src/components/add-word-form.jsx index 0b3cd29..96f9bc0 100644 --- a/src/components/add-word-form.jsx +++ b/src/components/add-word-form.jsx @@ -8,13 +8,13 @@ import {ScrollView} from 'react-native'; const AddWordForm = props => { return ( + {props.ankiLanModelExists ?
    - : - } + }
    ) } diff --git a/src/components/view/add-main-template.jsx b/src/components/view/add-main-template.jsx index 044d89f..7f843d3 100644 --- a/src/components/view/add-main-template.jsx +++ b/src/components/view/add-main-template.jsx @@ -6,14 +6,14 @@ import {createAnkiLanModel} from '../../actions/createAnkiLanModel'; const AnkiTemplate = props => { useEffect(() => { - props.checkAnkiLanModelForExisting(props.id) + props.checkAnkiLanModelForExisting(props.modelName) }, []) return( You have no AnkiLan card template @@ -22,8 +22,8 @@ const AnkiTemplate = props => { } export default connect(state => ({ - modelId: state.anki.ankiLanModelID, - modelName: state.anki.ankiLanModelName + modelName: state.anki.ankiLanModelName, + currentDeck: state.anki.selectedDeck }), { createAnkiLanModel, checkAnkiLanModelForExisting diff --git a/src/components/view/deck-picker.jsx b/src/components/view/deck-picker.jsx index be9b43e..9c06b58 100644 --- a/src/components/view/deck-picker.jsx +++ b/src/components/view/deck-picker.jsx @@ -1,17 +1,20 @@ import React, {useEffect, useState} from 'react' import {connect} from 'react-redux' import {Picker, Text} from 'native-base' -import { getDeckList} from '../../actions/anki-get-actions'; +import { getDeckList, getModelList} from '../../actions/anki-get-actions'; import {selectDeck} from '../../actions/anki-set-actions'; const DeckPicker = props => { const [deckList, setDeckList] = useState([{name: "no decks", id: 0}]); useEffect(() => { props.getDeckList() - setDeckList(props.decks) + props.getModelList() }, []) + useEffect(() => { + setDeckList(props.decks) + }, [props.decks]) return ( - props.selectDeck(id)} selectedValue={props.selectedDeck} > + props.selectDeck({id, deck: deckList[id]})} selectedValue={props.selectedDeck.id}> {deckList.map((deck, index) => ( ))} @@ -24,5 +27,6 @@ export default connect(state => ({ selectedDeck: state.anki.selectedDeck }),{ getDeckList, - selectDeck + selectDeck, + getModelList })(DeckPicker) diff --git a/src/reducers/anki-reducer.js b/src/reducers/anki-reducer.js index a30c850..9a9969d 100644 --- a/src/reducers/anki-reducer.js +++ b/src/reducers/anki-reducer.js @@ -1,5 +1,6 @@ import { GET_DECK_LIST, + GET_MODEL_LIST, REQUEST_PERMISSIONS, SET_DECK, SET_EXISTING_OF_ANKI_LAN_MODEL, @@ -9,12 +10,15 @@ const initialState = { isApiAvailable: false, appHasAccess: false, deckList: [], - selectedDeck: '1', + modelList: [], + selectedDeck: { + id: '1', + deck: Object, + }, mainFieldIsAvailable: false, fieldList: [], ankiLanModelIsAlreadyExists: false, - ankiLanModelID: '7410448765670', - ankiLanModelName: 'AnkiLan', + ankiLanModelName: 'AnkiLan_test', }; const ankiReducer = (state = initialState, action) => { @@ -24,8 +28,13 @@ const ankiReducer = (state = initialState, action) => { return {...state, appHasAccess: action.payload}; case GET_DECK_LIST: return {...state, deckList: action.payload}; + case GET_MODEL_LIST: + return {...state, modelList: action.payload}; case SET_DECK: - return {...state, selectedDeck: action.payload}; + return { + ...state, + selectedDeck: {...state.selectedDeck, ...action.payload}, + }; case SET_EXISTING_OF_ANKI_LAN_MODEL: return {...state, ankiLanModelIsAlreadyExists: action.payload}; default: