2019-05-30 14:21:09 -06:00
import { renderDictionaryDetails , renderPartsOfSpeech , renderAll , renderWords } from "./render" ;
2019-05-10 15:39:00 -06:00
import { removeTags , cloneObject , getTimestampInSeconds , download , slugify } from "../helpers" ;
2019-05-08 16:19:11 -06:00
import { LOCAL _STORAGE _KEY , DEFAULT _DICTIONARY , MIGRATE _VERSION } from "../constants" ;
2019-05-23 12:03:25 -06:00
import { addMessage , getNextId , hasToken } from "./utilities" ;
2019-05-24 14:01:48 -06:00
import { addWord , sortWords } from "./wordManagement" ;
2019-05-03 21:52:19 -06:00
export function updateDictionary ( ) {
renderDictionaryDetails ( ) ;
}
export function openEditModal ( ) {
2019-05-03 23:58:49 -06:00
const { name , specification , description , partsOfSpeech } = window . currentDictionary ;
const { consonants , vowels , blends , phonotactics } = window . currentDictionary . details . phonology ;
const { orthography , grammar } = window . currentDictionary . details ;
2019-05-24 15:09:57 -06:00
const { allowDuplicates , caseSensitive , sortByDefinition , isPublic } = window . currentDictionary . settings ;
2019-05-03 23:58:49 -06:00
document . getElementById ( 'editName' ) . value = name ;
document . getElementById ( 'editSpecification' ) . value = specification ;
document . getElementById ( 'editDescription' ) . value = description ;
document . getElementById ( 'editPartsOfSpeech' ) . value = partsOfSpeech . join ( ',' ) ;
2019-05-10 15:52:20 -06:00
document . getElementById ( 'editConsonants' ) . value = consonants . join ( ' ' ) ;
document . getElementById ( 'editVowels' ) . value = vowels . join ( ' ' ) ;
document . getElementById ( 'editBlends' ) . value = blends . join ( ' ' ) ;
2019-05-03 23:58:49 -06:00
document . getElementById ( 'editOnset' ) . value = phonotactics . onset . join ( ',' ) ;
document . getElementById ( 'editNucleus' ) . value = phonotactics . nucleus . join ( ',' ) ;
document . getElementById ( 'editCoda' ) . value = phonotactics . coda . join ( ',' ) ;
document . getElementById ( 'editExceptions' ) . value = phonotactics . exceptions ;
document . getElementById ( 'editOrthography' ) . value = orthography . notes ;
document . getElementById ( 'editGrammar' ) . value = grammar . notes ;
2019-05-06 14:30:57 -06:00
document . getElementById ( 'editPreventDuplicates' ) . checked = ! allowDuplicates ;
2019-05-04 00:21:55 -06:00
document . getElementById ( 'editCaseSensitive' ) . checked = caseSensitive ;
2019-05-06 14:30:57 -06:00
if ( allowDuplicates ) document . getElementById ( 'editCaseSensitive' ) . disabled = true ;
2019-05-04 00:21:55 -06:00
document . getElementById ( 'editSortByDefinition' ) . checked = sortByDefinition ;
2019-05-24 15:37:15 -06:00
if ( hasToken ( ) ) {
document . getElementById ( 'editIsPublic' ) . checked = isPublic ;
}
2019-05-04 00:21:55 -06:00
document . getElementById ( 'editModal' ) . style . display = '' ;
}
2019-05-08 15:23:46 -06:00
export function saveEditModal ( ) {
2019-05-04 00:21:55 -06:00
window . currentDictionary . name = removeTags ( document . getElementById ( 'editName' ) . value . trim ( ) ) ;
window . currentDictionary . specification = removeTags ( document . getElementById ( 'editSpecification' ) . value . trim ( ) ) ;
window . currentDictionary . description = removeTags ( document . getElementById ( 'editDescription' ) . value . trim ( ) ) ;
2019-05-08 15:23:46 -06:00
window . currentDictionary . partsOfSpeech = document . getElementById ( 'editPartsOfSpeech' ) . value . split ( ',' ) . map ( val => val . trim ( ) ) . filter ( val => val !== '' ) ;
2019-05-10 15:52:20 -06:00
window . currentDictionary . details . phonology . consonants = document . getElementById ( 'editConsonants' ) . value . split ( ' ' ) . map ( val => val . trim ( ) ) . filter ( val => val !== '' ) ;
window . currentDictionary . details . phonology . vowels = document . getElementById ( 'editVowels' ) . value . split ( ' ' ) . map ( val => val . trim ( ) ) . filter ( val => val !== '' ) ;
window . currentDictionary . details . phonology . blends = document . getElementById ( 'editBlends' ) . value . split ( ' ' ) . map ( val => val . trim ( ) ) . filter ( val => val !== '' ) ;
2019-05-08 15:23:46 -06:00
window . currentDictionary . details . phonology . phonotactics . onset = document . getElementById ( 'editOnset' ) . value . split ( ',' ) . map ( val => val . trim ( ) ) . filter ( val => val !== '' ) ;
window . currentDictionary . details . phonology . phonotactics . nucleus = document . getElementById ( 'editNucleus' ) . value . split ( ',' ) . map ( val => val . trim ( ) ) . filter ( val => val !== '' ) ;
window . currentDictionary . details . phonology . phonotactics . coda = document . getElementById ( 'editCoda' ) . value . split ( ',' ) . map ( val => val . trim ( ) ) . filter ( val => val !== '' ) ;
2019-05-04 00:21:55 -06:00
window . currentDictionary . details . phonology . phonotactics . exceptions = removeTags ( document . getElementById ( 'editExceptions' ) . value . trim ( ) ) ;
window . currentDictionary . details . orthography . notes = removeTags ( document . getElementById ( 'editOrthography' ) . value . trim ( ) ) ;
window . currentDictionary . details . grammar . notes = removeTags ( document . getElementById ( 'editGrammar' ) . value . trim ( ) ) ;
2019-05-06 14:30:57 -06:00
window . currentDictionary . settings . allowDuplicates = ! document . getElementById ( 'editPreventDuplicates' ) . checked ;
2019-05-04 00:21:55 -06:00
window . currentDictionary . settings . caseSensitive = document . getElementById ( 'editCaseSensitive' ) . checked ;
2019-05-24 14:01:48 -06:00
const needsReSort = window . currentDictionary . settings . sortByDefinition !== document . getElementById ( 'editSortByDefinition' ) . checked ;
2019-05-04 00:21:55 -06:00
window . currentDictionary . settings . sortByDefinition = document . getElementById ( 'editSortByDefinition' ) . checked ;
2019-05-30 14:21:09 -06:00
let needsWordRender = false ;
2019-05-24 15:37:15 -06:00
if ( hasToken ( ) ) {
2019-05-30 14:21:09 -06:00
needsWordRender = window . currentDictionary . settings . isPublic !== document . getElementById ( 'editIsPublic' ) . checked ;
2019-05-24 15:37:15 -06:00
window . currentDictionary . settings . isPublic = document . getElementById ( 'editIsPublic' ) . checked ;
} else {
window . currentDictionary . settings . isPublic = false ;
}
2019-05-04 00:21:55 -06:00
2019-05-09 14:34:32 -06:00
addMessage ( 'Saved ' + window . currentDictionary . specification + ' Successfully' ) ;
2019-05-08 15:23:46 -06:00
saveDictionary ( ) ;
2019-05-04 00:21:55 -06:00
renderDictionaryDetails ( ) ;
2019-05-05 12:00:32 -06:00
renderPartsOfSpeech ( ) ;
2019-05-30 14:21:09 -06:00
if ( needsReSort || needsWordRender ) {
2019-05-24 14:01:48 -06:00
sortWords ( true ) ;
}
2019-05-23 12:03:25 -06:00
if ( hasToken ( ) ) {
import ( './account/index.js' ) . then ( account => {
account . uploadDetailsDirect ( ) ;
2019-05-23 17:00:13 -06:00
account . updateChangeDictionaryOption ( ) ;
2019-05-23 12:03:25 -06:00
} )
}
2019-05-04 00:21:55 -06:00
}
2019-05-08 15:23:46 -06:00
export function saveAndCloseEditModal ( ) {
saveEditModal ( ) ;
2019-05-04 00:21:55 -06:00
document . getElementById ( 'editModal' ) . style . display = 'none' ;
2019-05-03 21:52:19 -06:00
}
2019-05-23 14:26:57 -06:00
export function saveDictionary ( triggerLastUpdated = true ) {
if ( triggerLastUpdated ) {
window . currentDictionary . lastUpdated = getTimestampInSeconds ( ) ;
}
2019-05-08 15:23:46 -06:00
window . localStorage . setItem ( LOCAL _STORAGE _KEY , JSON . stringify ( window . currentDictionary ) ) ;
}
2019-05-03 21:52:19 -06:00
2019-05-08 15:23:46 -06:00
export function loadDictionary ( ) {
const storedDictionary = window . localStorage . getItem ( LOCAL _STORAGE _KEY ) ;
if ( storedDictionary ) {
window . currentDictionary = JSON . parse ( storedDictionary ) ;
2019-05-08 16:19:11 -06:00
migrateDictionary ( ) ;
2019-05-08 15:23:46 -06:00
} else {
clearDictionary ( ) ;
}
}
export function clearDictionary ( ) {
window . currentDictionary = cloneObject ( DEFAULT _DICTIONARY ) ;
}
2019-05-08 16:19:11 -06:00
2019-05-13 10:49:52 -06:00
export function deleteDictionary ( ) {
2019-05-23 19:56:45 -06:00
const deletedId = window . currentDictionary . externalID ;
2019-05-13 10:49:52 -06:00
clearDictionary ( ) ;
saveDictionary ( ) ;
addMessage ( 'Dictionary Deleted!' ) ;
renderAll ( ) ;
2019-05-23 19:56:45 -06:00
if ( hasToken ( ) ) {
import ( './account/index.js' ) . then ( account => {
account . deleteCurrentDictionary ( deletedId ) ;
} ) ;
}
2019-05-13 10:49:52 -06:00
}
export function confirmDeleteDictionary ( ) {
if ( confirm ( ` Are you sure you want to delete your ${ window . currentDictionary . name } ${ window . currentDictionary . specification } ? \n \n This cannot be undone! ` ) ) {
const input = prompt ( ` If you really want to delete your ${ window . currentDictionary . name } ${ window . currentDictionary . specification } please type DELETE in the text box. \n \n After you confirm, cour dicitonary will be PERMANENTLY AND IRRETRIEVABLY DESTROYED! ` ) ;
console . log ( input ) ;
if ( input === 'DELETE' ) {
deleteDictionary ( ) ;
document . getElementById ( 'editModal' ) . style . display = 'none' ;
} else {
alert ( 'Your dictionary was NOT deleted' ) ;
}
}
}
2019-05-10 15:39:00 -06:00
export function importDictionary ( ) {
const importDictionaryField = document . getElementById ( 'importDictionaryFile' ) ;
if ( importDictionaryField . files . length === 1 ) {
if ( confirm ( 'Importing a dicitonary file will overwrite and replace your current dictionary!\nDo you want to continue?' ) ) {
addMessage ( 'Importing Dictionary...' ) ;
const fileReader = new FileReader ( ) ;
fileReader . onload = function ( fileLoadedEvent ) {
const textFromFileLoaded = fileLoadedEvent . target . result ;
const importedDictionary = JSON . parse ( textFromFileLoaded ) ;
if ( importedDictionary && importedDictionary . hasOwnProperty ( 'words' ) ) {
2019-05-23 14:42:09 -06:00
const timestamp = getTimestampInSeconds ( ) ;
if ( ! importedDictionary . hasOwnProperty ( 'createdOn' ) ) {
importedDictionary . createdOn = timestamp ;
}
if ( importedDictionary . words . some ( word => ! word . hasOwnProperty ( 'createdOn' ) ) ) {
importedDictionary . words . forEach ( word => {
if ( ! word . hasOwnProperty ( 'createdOn' ) ) {
word . createdOn = timestamp ;
}
if ( ! word . hasOwnProperty ( 'lastUpdated' ) ) {
word . lastUpdated = timestamp ;
}
} ) ;
}
if ( importedDictionary . hasOwnProperty ( 'externalID' ) ) {
delete importedDictionary . externalID ;
}
2019-05-10 15:39:00 -06:00
window . currentDictionary = importedDictionary ;
saveDictionary ( ) ;
renderAll ( ) ;
importDictionaryField . value = '' ;
document . getElementById ( 'editModal' ) . style . display = 'none' ;
addMessage ( 'Dictionary Imported Successfully' ) ;
2019-05-23 12:03:25 -06:00
if ( hasToken ( ) ) {
import ( './account/index.js' ) . then ( account => {
account . syncImportedDictionary ( ) ;
} ) ;
}
2019-05-10 15:39:00 -06:00
} else {
2019-05-23 15:24:56 -06:00
addMessage ( 'Dictionary could not be imported' , 10000 , 'error' ) ;
2019-05-10 15:39:00 -06:00
}
} ;
fileReader . readAsText ( importDictionaryField . files [ 0 ] , "UTF-8" ) ;
}
}
}
export function importWords ( ) {
const importWordsField = document . getElementById ( 'importWordsCSV' ) ;
if ( importWordsField . files . length === 1 ) {
if ( confirm ( 'Importing a CSV file with words will add all of the words in the file to your dictionary regardless of duplication!\nDo you want to continue?' ) ) {
addMessage ( 'Importing words...' ) ;
import ( 'papaparse' ) . then ( papa => {
2019-05-23 12:03:25 -06:00
const importedWords = [ ] ;
2019-05-10 15:39:00 -06:00
papa . parse ( importWordsField . files [ 0 ] , {
header : true ,
encoding : "utf-8" ,
step : results => {
if ( results . errors . length > 0 ) {
results . errors . forEach ( err => {
2019-05-23 15:24:56 -06:00
addMessage ( 'Error Importing Word: ' + err , undefined , 'error' ) ;
2019-05-10 15:39:00 -06:00
console . error ( 'Error Importing Word: ' , err )
} ) ;
} else {
const row = results . data [ 0 ] ;
2019-05-23 12:03:25 -06:00
const importedWord = addWord ( {
2019-05-10 15:39:00 -06:00
name : removeTags ( row . word ) . trim ( ) ,
pronunciation : removeTags ( row . pronunciation ) . trim ( ) ,
partOfSpeech : removeTags ( row [ 'part of speech' ] ) . trim ( ) ,
definition : removeTags ( row . definition ) . trim ( ) ,
details : removeTags ( row . explanation ) . trim ( ) ,
wordId : getNextId ( ) ,
2019-05-23 12:03:25 -06:00
} , false , false , false ) ;
importedWords . push ( importedWord ) ;
2019-05-10 15:39:00 -06:00
}
} ,
complete : ( ) => {
2019-05-23 14:26:57 -06:00
saveDictionary ( false ) ;
2019-05-10 15:39:00 -06:00
renderAll ( ) ;
importWordsField . value = '' ;
document . getElementById ( 'editModal' ) . style . display = 'none' ;
2019-05-23 12:03:25 -06:00
addMessage ( ` Done Importing ${ importedWords . length } Words ` ) ;
if ( hasToken ( ) ) {
import ( './account/index.js' ) . then ( account => {
account . syncImportedWords ( importedWords ) ;
} ) ;
}
2019-05-10 15:39:00 -06:00
} ,
error : err => {
2019-05-23 15:24:56 -06:00
addMessage ( 'Error Importing Words: ' + err , undefined , 'error' ) ;
2019-05-10 15:39:00 -06:00
console . error ( 'Error Importing Words: ' , err ) ;
} ,
skipEmptyLines : true ,
} ) ;
} ) ;
}
}
}
export function exportDictionary ( ) {
addMessage ( 'Exporting JSON...' ) ;
setTimeout ( ( ) => {
const file = JSON . stringify ( window . currentDictionary ) ,
{ name , specification } = window . currentDictionary ;
const fileName = slugify ( name + '_' + specification ) + '.json' ;
download ( file , fileName , 'application/json;charset=utf-8' ) ;
} , 1 ) ;
}
export function exportWords ( ) {
addMessage ( 'Exporting Words...' ) ;
setTimeout ( ( ) => {
import ( 'papaparse' ) . then ( papa => {
const { name , specification } = window . currentDictionary ;
const fileName = slugify ( name + '_' + specification ) + '_words.csv' ;
const words = window . currentDictionary . words . map ( word => {
return {
word : word . name ,
pronunciation : word . pronunciation ,
'part of speech' : word . partOfSpeech ,
definition : word . definition ,
explanation : word . details ,
}
} ) ;
const csv = papa . unparse ( words , { quotes : true } ) ;
download ( csv , fileName , 'text/csv;charset=utf-8' ) ;
} ) ;
} , 1 ) ;
}
2019-05-08 16:19:11 -06:00
export function migrateDictionary ( ) {
let migrated = false ;
if ( ! window . currentDictionary . hasOwnProperty ( 'version' ) ) {
const fixStupidOldNonsense = string => string . replace ( /"/g , '"' ) . replace ( /'/g , "'" ) . replace ( /\/g , '\\' ) . replace ( /<br>/g , '\n' ) ;
window . currentDictionary . description = fixStupidOldNonsense ( window . currentDictionary . description ) ;
2019-05-23 14:42:09 -06:00
const timestamp = getTimestampInSeconds ( ) ;
2019-05-08 16:19:11 -06:00
window . currentDictionary . words = window . currentDictionary . words . map ( word => {
2019-05-10 10:08:49 -06:00
word . definition = word . simpleDefinition ;
delete word . simpleDefinition ;
word . details = fixStupidOldNonsense ( word . longDefinition ) ;
delete word . longDefinition ;
2019-05-23 14:42:09 -06:00
word . lastUpdated = timestamp ;
word . createdOn = timestamp ;
2019-05-08 16:19:11 -06:00
return word ;
} ) ;
window . currentDictionary = Object . assign ( { } , DEFAULT _DICTIONARY , window . currentDictionary ) ;
window . currentDictionary . partsOfSpeech = window . currentDictionary . settings . partsOfSpeech . split ( ',' ) . map ( val => val . trim ( ) ) . filter ( val => val !== '' ) ;
delete window . currentDictionary . settings . partsOfSpeech ;
window . currentDictionary . settings . sortByDefinition = window . currentDictionary . settings . sortByEquivalent ;
delete window . currentDictionary . settings . sortByEquivalent ;
migrated = true ;
} else if ( window . currentDictionary . version !== MIGRATE _VERSION ) {
switch ( window . currentDictionary . version ) {
default : console . error ( 'Unknown version' ) ; break ;
}
}
if ( migrated ) {
saveDictionary ( ) ;
}
}