From b7308a1f70c97cd3634b9ce12d93e7f8360961c0 Mon Sep 17 00:00:00 2001 From: "[1000i100] Millicent Billette" <git@1000i100.fr> Date: Mon, 2 Jan 2023 07:29:16 +0100 Subject: [PATCH] =?UTF-8?q?v3.0.0-alpha6=20Corrections=20multiples=20bug?= =?UTF-8?q?=20am=C3=A9liorations=20d'ergonomie=20Options=20d'interface=20c?= =?UTF-8?q?ompl=C3=A8tes=20TODO:=20-=20doc=20/=20guide=20interactif=20-=20?= =?UTF-8?q?auto-save/resume=20-=20responsive=20-=20pub=20offline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 14 +++++------ package.json | 2 +- src/js/logic/dico.mjs | 3 +++ src/js/logic/saveResume.mjs | 29 +++++++++++++++++++++++ src/js/logic/search.mjs | 9 +++++--- src/js/logic/utils.mjs | 10 ++++++++ src/js/logic/workerManager.mjs | 5 ++-- src/js/ux/1_pubKey.mjs | 6 +++-- src/js/ux/2_inputSecrets.mjs | 37 +++++++++++++++++++++++++++++- src/js/ux/3_inProgress.mjs | 2 +- src/js/ux/4_result.mjs | 9 ++++++-- src/js/ux/nav.mjs | 12 ++++++++-- src/js/ux/rangeOption.mjs | 1 + src/pages/fragments/browse.ejs | 7 ++++-- src/pages/steps/1_pubKey.ejs | 9 ++++++++ src/pages/steps/2_inputSecrets.ejs | 7 ++---- src/pages/steps/4_result.ejs | 2 +- 17 files changed, 134 insertions(+), 30 deletions(-) create mode 100644 src/js/logic/saveResume.mjs create mode 100644 src/js/logic/utils.mjs diff --git a/package-lock.json b/package-lock.json index 9822cb6..b27b35d 100755 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "hasInstallScript": true, "dependencies": { - "g1lib": "^3.5.5" + "g1lib": "^3.5.7" }, "devDependencies": { "@fortawesome/fontawesome-free": "^5.15.2", @@ -1004,9 +1004,9 @@ } }, "node_modules/g1lib": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.5.tgz", - "integrity": "sha512-3JnCfMOc2ynTgCv4MsoeEAT9gGkwYMehFULOx6kMNY0tlPu1ytMI40UtcFPjCMUxnAXhBixtUTgbf8u1UxlgMA==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.7.tgz", + "integrity": "sha512-gxCMQvn4wl8huRwUiW2zc2Bvul2ch+7VB2dHcbJkME1TLivpx/azljA3OGnhhfMJG93mGZvHoBxCFnqOqmqb1A==", "funding": { "url": "https://git.duniter.org/libs/g1lib.js" } @@ -4456,9 +4456,9 @@ "dev": true }, "g1lib": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.5.tgz", - "integrity": "sha512-3JnCfMOc2ynTgCv4MsoeEAT9gGkwYMehFULOx6kMNY0tlPu1ytMI40UtcFPjCMUxnAXhBixtUTgbf8u1UxlgMA==" + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.7.tgz", + "integrity": "sha512-gxCMQvn4wl8huRwUiW2zc2Bvul2ch+7VB2dHcbJkME1TLivpx/azljA3OGnhhfMJG93mGZvHoBxCFnqOqmqb1A==" }, "get-caller-file": { "version": "2.0.5", diff --git a/package.json b/package.json index faa6ae2..cf2ebb5 100755 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "build:stylus": "stylus --include-css src/stylus/_all.styl -o generated/public/style.css" }, "dependencies": { - "g1lib": "^3.5.5" + "g1lib": "^3.5.7" }, "devDependencies": { "@fortawesome/fontawesome-free": "^5.15.2", diff --git a/src/js/logic/dico.mjs b/src/js/logic/dico.mjs index 90705ca..bce5fce 100755 --- a/src/js/logic/dico.mjs +++ b/src/js/logic/dico.mjs @@ -2,6 +2,7 @@ import {subscribe} from "./workerManager.mjs"; import getCombiPerSec from "./speedBench.mjs"; import {Dictionary} from "g1lib/browser/dictionary.mjs"; import staticPreview from "./staticPreview.mjs"; +import {cacheScale} from "./search.mjs"; let currentDico; let lastData; @@ -52,6 +53,8 @@ export function getActualData(withSpeed = true) { accent:so.accent.value<0?undefined:so.accent.value, lowerCase:so.caps.value<0?undefined:so.caps.value, leetSpeak:0, + save:so.save.value, + cacheMax:cacheScale[so.cacheMax.value], }, previewIndex: (window.browseIndex || 0), }; diff --git a/src/js/logic/saveResume.mjs b/src/js/logic/saveResume.mjs new file mode 100644 index 0000000..b451e58 --- /dev/null +++ b/src/js/logic/saveResume.mjs @@ -0,0 +1,29 @@ +import {subscribe} from "./workerManager.mjs"; +import {swapKeyValue,sleep} from "./utils.mjs"; + +export const saveScale = []; +saveScale[0]=0; +saveScale[1]=24*60*60; +saveScale[2]=2*24*60*60; +saveScale[3]=7*24*60*60; +export const revertSaveScale = swapKeyValue(saveScale); + +const MIN_COMPUTE_TIME_FOR_SAVE = 3600; + +export let saveMode=0 + +async function init(){ + await sleep(1); + subscribe('smartPreview', updateSaveMode); + window.searchOptions.save.listen('saveResume',manualUpdate); +} +init(); +function manualUpdate(mode){ + if(mode>=0) saveMode = saveScale[mode]; +} +function updateSaveMode(data){ + const smartDico = JSON.parse(data.dico); + if(smartDico.config.save<0) saveMode = smartDico.estimateDuration >= MIN_COMPUTE_TIME_FOR_SAVE ? saveScale[2] : 0; + else saveMode = saveScale[smartDico.config.save]; + window.searchOptions.save.setComputed(revertSaveScale[saveMode]); +} diff --git a/src/js/logic/search.mjs b/src/js/logic/search.mjs index 0ada2e7..d71ea42 100644 --- a/src/js/logic/search.mjs +++ b/src/js/logic/search.mjs @@ -10,7 +10,9 @@ export let departTime; export let endTime; export let found; export let cacheActive = true; -export const CACHE_MAX = 1_000_000; +export const DEFAULT_CACHE_MAX = 1_000_000; +export const cacheScale = []; + const globalCache = {}; export function duplicateCount() { @@ -53,6 +55,7 @@ export function stopSearch() { function updateProgress(data) { if (data.bench) return; tested++; + if(found) endSearchTest(); if (data.publicKey === pubKey) { endSearchTest(data); } else { @@ -61,9 +64,9 @@ function updateProgress(data) { if (!globalCache[cacheKey]) globalCache[cacheKey] = {}; globalCache[cacheKey][data.index] = true; } - if (Object.keys(globalCache).length > CACHE_MAX) cacheActive = false; + if (Object.keys(globalCache).length > getDico().config.cacheMax) cacheActive = false; } - if (tested >= getDico().length) endSearchTest() + if (tested >= getDico().length) endSearchTest(); } function endSearchTest(somethingFound = undefined) { diff --git a/src/js/logic/utils.mjs b/src/js/logic/utils.mjs new file mode 100644 index 0000000..8139f09 --- /dev/null +++ b/src/js/logic/utils.mjs @@ -0,0 +1,10 @@ +export function swapKeyValue(object) { + const result = {}; + for (const key in object) { + result[object[key]] = key; + } + return result; +} +export async function sleep(ms) { + return new Promise((resolve, reject) => setTimeout(resolve, ms)); +} diff --git a/src/js/logic/workerManager.mjs b/src/js/logic/workerManager.mjs index 64462bf..2a16ab8 100644 --- a/src/js/logic/workerManager.mjs +++ b/src/js/logic/workerManager.mjs @@ -1,3 +1,5 @@ +import {sleep} from "./utils.mjs"; + const workers = []; const MAX_ALLOWED_IN_QUEUE = 5; const subscriptionList = {}; @@ -56,6 +58,3 @@ export function unSubscribe(action,registeredFunc){ const index = subscriptionList[action].indexOf(registeredFunc); subscriptionList[action].splice(index, 1); } -async function sleep(ms) { - return new Promise((resolve, reject) => setTimeout(resolve, ms)); -} diff --git a/src/js/ux/1_pubKey.mjs b/src/js/ux/1_pubKey.mjs index eec4f61..443e956 100644 --- a/src/js/ux/1_pubKey.mjs +++ b/src/js/ux/1_pubKey.mjs @@ -14,8 +14,10 @@ export default function focus_1_pubKey(){ export let pubKey; export function updatePubKey(){ const pubKeyInputNode = document.getElementById('pubKey'); - if(location.hash.match(/pubkey=/i) !== null) - pubKeyInputNode.value = location.hash.split('=')[1]; + if(location.hash.match(/pubkey=/i) !== null){ + pubKeyInputNode.value = location.hash.split('=')[1]; + return location.hash = location.hash.split('=')[0]; + } pubKey = pubKeyInputNode.value; const nextBtn = document.querySelector('.step_1_pubKey a.button'); const errorArea = document.querySelector('.step_1_pubKey .warning'); diff --git a/src/js/ux/2_inputSecrets.mjs b/src/js/ux/2_inputSecrets.mjs index 97d63b5..8aba54a 100755 --- a/src/js/ux/2_inputSecrets.mjs +++ b/src/js/ux/2_inputSecrets.mjs @@ -4,6 +4,9 @@ import {timeUnitStrings} from "pretty-ms"; import {sendToWorker, subscribe} from "../logic/workerManager.mjs"; import {getActualData} from "../logic/dico.mjs"; import RangeOption from "./rangeOption.mjs"; +import {cacheScale, DEFAULT_CACHE_MAX} from "../logic/search.mjs"; +import {saveScale} from "../logic/saveResume.mjs"; +import {swapKeyValue} from "../logic/utils.mjs"; const regexDesc = { '-1': 'Syntaxe : auto-sélection', @@ -28,6 +31,36 @@ const capsDesc = { '1': `Majuscules : classiques`, '2': `Majuscules : fluctuantes`, } + + +const saveDesc = { + '-1': `Reprendre : auto-sélection`, + '0': `Reprendre : désactivé par sécurité`, + '1': `Reprendre : possible pendant 24h`, + '2': `Reprendre : possible pendant 48h`, + '3': `Reprendre : possible pendant 7j`, +} +cacheScale[-1]=DEFAULT_CACHE_MAX; +cacheScale[0]=0; +cacheScale[1]=10_000; +cacheScale[2]=100_000; +cacheScale[3]=1_000_000; +cacheScale[4]=10_000_000; +cacheScale[5]=100_000_000; +cacheScale[6]=1_000_000_000; +const revertCacheScale = swapKeyValue(cacheScale.filter((v,i)=> i>=0 )); + +const cacheMaxDesc = { + '-1': `Cache : auto-sélection`, + '0': `Cache : désactivé`, + '1': `Cache : ${cacheScale[1].toLocaleString('fr-FR')}`, + '2': `Cache : ${cacheScale[2].toLocaleString('fr-FR')}`, + '3': `Cache : ${cacheScale[3].toLocaleString('fr-FR')}`, + '4': `Cache : ${cacheScale[4].toLocaleString('fr-FR')}`, + '5': `Cache : ${cacheScale[5].toLocaleString('fr-FR')}`, + '6': `Cache : ${cacheScale[6].toLocaleString('fr-FR')}`, +// '6': `Cache : ${new Intl.NumberFormat().format(cacheScale[6])}`, +} export function init() { const secretsInputNode = document.getElementById('secrets'); secretsInputNode.addEventListener('keyup', askPreview); @@ -38,7 +71,8 @@ export function init() { 'mirror': new RangeOption('mirror', -1, mirrorDesc, askPreview), 'accent': new RangeOption('accent', -1, accentDesc, askPreview), 'caps': new RangeOption('caps', -1, capsDesc, askPreview), - //TODO: AutoSave & resume + 'save': new RangeOption('save', -1, saveDesc, askPreview), + 'cacheMax': new RangeOption('cacheMax', -1, cacheMaxDesc, askPreview), }; subscribe('fastPreview',updateFastPreviewDisplay); subscribe('smartPreview', updateSmartPreviewDisplay); @@ -93,6 +127,7 @@ function updateSmartPreviewDisplay(data){ so.accent.setComputed(sdc.accent || 0); so.caps.setComputed(sdc.lowerCase || 0); so.accent.setComputed(sdc.accent || 0); + so.cacheMax.setComputed(revertCacheScale[sdc.cacheMax]); try{window.displayBrowsePreview();}catch (e){} } diff --git a/src/js/ux/3_inProgress.mjs b/src/js/ux/3_inProgress.mjs index e954879..294624d 100644 --- a/src/js/ux/3_inProgress.mjs +++ b/src/js/ux/3_inProgress.mjs @@ -8,7 +8,7 @@ export default function init(){ setInterval(showProgress,200); } init(); -const progressColor = getComputedStyle(document.getElementById('startSearch')).color; +const progressColor = getComputedStyle(document.querySelector('.success h3')).color; const progressBar = document.getElementById('progress_bar'); const bgColor = getComputedStyle(progressBar).backgroundColor; const timing = []; diff --git a/src/js/ux/4_result.mjs b/src/js/ux/4_result.mjs index 97d8157..381f5ab 100644 --- a/src/js/ux/4_result.mjs +++ b/src/js/ux/4_result.mjs @@ -21,8 +21,13 @@ export default function showResult(){ document.getElementById('resSpent').innerHTML = timeFormat(timeSpent); document.getElementById('resSpeed').innerHTML = (1000*tested/timeSpent).toFixed(1); const duplicates = duplicateCount(); - document.getElementById('resDuplicate').innerHTML = duplicates; - document.getElementById('resDupRatio').innerHTML = (100 * duplicates / tested).toPrecision(3); + if (duplicates) { + document.getElementById('resDup').classList.remove('hidden'); + document.getElementById('resDuplicate').innerHTML = duplicates; + document.getElementById('resDupRatio').innerHTML = (100 * duplicates / tested).toPrecision(3); + } else { + document.getElementById('resDup').classList.add('hidden'); + } } function timeFormat(milliseconds) { return prettyMilliseconds(Math.trunc(milliseconds / 1000)*1000, { diff --git a/src/js/ux/nav.mjs b/src/js/ux/nav.mjs index 2be619d..4fbc8fd 100644 --- a/src/js/ux/nav.mjs +++ b/src/js/ux/nav.mjs @@ -16,6 +16,14 @@ const setFocus = [ ()=>0, showResult, ]; + +const pages = [ + 'page_0_home', + 'page_1_pubKey', + 'page_2_inputSecrets', + 'page_3_inProgress', + 'page_4_result', +]; init(); // internal navigation @@ -25,8 +33,8 @@ function showPageFromHash(){ const pageNumber = parseInt(window.location.hash.split('_')[1]); if(isNaN(pageNumber)) return window.location = '#page_0_home'; if(pageNumber<2 || pubKey){ - document.body.className = window.location.hash.slice(1) - } else window.location = '#page_0_home'; + document.body.className = pages[pageNumber] + } else return window.location = '#page_0_home'; setFocus[pageNumber](); if(pageNumber!==3) stopSearch(); } catch (e){ diff --git a/src/js/ux/rangeOption.mjs b/src/js/ux/rangeOption.mjs index fc6e4d1..78839f7 100644 --- a/src/js/ux/rangeOption.mjs +++ b/src/js/ux/rangeOption.mjs @@ -78,6 +78,7 @@ export default function RangeOption(fieldId, initialValue, descArray, uiListener Object.keys(self.listeners).forEach(k=>self.listeners[k](mode)); } checkBoxNode.addEventListener('change', ()=>uiChanged(hiddenNode.value = checkBoxNode.checked?-1:(rangeNode.value || 0))); + rangeNode.addEventListener('input', ()=>descLabel.innerHTML = descArray[rangeNode.value]); rangeNode.addEventListener('change', ()=>uiChanged(hiddenNode.value = rangeNode.value)); if(typeof uiListener !== 'undefined') self.listen('default',uiListener) if(initialValue) self.setUserChoice(initialValue); diff --git a/src/pages/fragments/browse.ejs b/src/pages/fragments/browse.ejs index 9ef4f7b..d3dc5c6 100644 --- a/src/pages/fragments/browse.ejs +++ b/src/pages/fragments/browse.ejs @@ -135,11 +135,14 @@ return (index + staticDico.length) % staticDico.length; } function updateBrowseIndex(e){ - if(e && e.key === "ArrowUp") return browseUp(); - if(e && e.key === "ArrowDown") return browseDown(); + if(e && e.key && e.key === "ArrowUp") return browseUp(); + if(e && e.key && e.key === "ArrowDown") return browseDown(); + if(e && e.deltaY && e.deltaY >0) return browseDown(); + if(e && e.deltaY && e.deltaY <0) return browseUp(); window.browseIndex = parseInt(document.querySelector('.currentIndex input').value); displayBrowsePreview(); } document.querySelector('.currentIndex input').addEventListener('keyup',updateBrowseIndex); + document.querySelector('.browse tbody').addEventListener('wheel',updateBrowseIndex); </script> </section> diff --git a/src/pages/steps/1_pubKey.ejs b/src/pages/steps/1_pubKey.ejs index 3c8d497..e8b5c76 100644 --- a/src/pages/steps/1_pubKey.ejs +++ b/src/pages/steps/1_pubKey.ejs @@ -11,4 +11,13 @@ <a href="#page_2_inputSecrets" class="button"> Suivant <i class="fas fa-long-arrow-alt-right"></i> </a> + <div class="notice"> + Vous êtes juste là pour tester, sans compte à récupérer ? + Voici une clef publique valide utilisable comme exemple : + <a href="#page_1_pubKey=BCHERdQbh3HhyDSoqHdXTyGQZLZvDA9b6DBABcMAPdDW">BCHERdQbh3HhyDSoqHdXTyGQZLZvDA9b6DBABcMAPdDW</a> + <!-- + idSec : "Ça me serait pas venu à l'idée !" + mdp : " MOI NON PLUS " + --> + </div> </section> diff --git a/src/pages/steps/2_inputSecrets.ejs b/src/pages/steps/2_inputSecrets.ejs index 1bbd0a2..e330644 100755 --- a/src/pages/steps/2_inputSecrets.ejs +++ b/src/pages/steps/2_inputSecrets.ejs @@ -15,11 +15,8 @@ <a id="startSearch" class="button" href="#page_3_inProgress">Valider</a> </div> <div class="inputArea"> - <textarea id="secrets"> -un exemple -un autre -le 3ème - </textarea> + <textarea id="secrets">ça (|ne )me serait pas venu[e]{0,1} à l'idée ! + moi non plus[ ]</textarea> <%- include('../fragments/browse.ejs'); %> </div> <div class="tabs"> diff --git a/src/pages/steps/4_result.ejs b/src/pages/steps/4_result.ejs index 341b7f7..3593442 100644 --- a/src/pages/steps/4_result.ejs +++ b/src/pages/steps/4_result.ejs @@ -18,7 +18,7 @@ </div> <div class="stats"> <div><span id="resTested"></span> combinaisons testées en <span id="resSpent"></span> (soit <span id="resSpeed"></span>/s)</div> - <div><span id="resDuplicate"></span> doublons évités soit <span id="resDupRatio"></span>% des combinaisons testées</div> + <div id="resDup"><span id="resDuplicate"></span> doublons évités soit <span id="resDupRatio"></span>% des combinaisons testées</div> </div> <div class="success"> <div class="gift notice"> -- GitLab