Better visual sync
This commit is contained in:
parent
40a68d6ad0
commit
d9c82868ab
6 changed files with 130 additions and 106 deletions
6
main.go
6
main.go
|
|
@ -25,7 +25,7 @@ import (
|
||||||
|
|
||||||
const VERSION = "v1"
|
const VERSION = "v1"
|
||||||
const CONTEXT_USER = 1
|
const CONTEXT_USER = 1
|
||||||
const SYNC_PAGINATION = 100
|
const SYNC_PAGINATION = 500
|
||||||
|
|
||||||
var (
|
var (
|
||||||
FlagGenerate bool
|
FlagGenerate bool
|
||||||
|
|
@ -269,9 +269,11 @@ func actionSyncFromServer(w http.ResponseWriter, r *http.Request) { // {{{
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
Log.Debug("/sync/from_server", "num_nodes", len(nodes), "maxSeq", maxSeq)
|
Log.Debug("/sync/from_server", "num_nodes", len(nodes), "maxSeq", maxSeq)
|
||||||
foo, _ := json.Marshal(nodes)
|
foo, _ := json.Marshal(nodes)
|
||||||
os.WriteFile(fmt.Sprintf("/tmp/nodes-%d.json", offset), foo, 0644)
|
os.WriteFile(fmt.Sprintf("/tmp/nodes-%d.json", offset), foo, 0644)
|
||||||
|
*/
|
||||||
|
|
||||||
j, _ := json.Marshal(struct {
|
j, _ := json.Marshal(struct {
|
||||||
OK bool
|
OK bool
|
||||||
|
|
@ -288,7 +290,6 @@ func actionSyncFromServerCount(w http.ResponseWriter, r *http.Request) { // {{{
|
||||||
user := getUser(r)
|
user := getUser(r)
|
||||||
changedFrom, _ := strconv.Atoi(r.PathValue("sequence"))
|
changedFrom, _ := strconv.Atoi(r.PathValue("sequence"))
|
||||||
|
|
||||||
Log.Debug("FOO", "UUID", user.ClientUUID, "changedFrom", changedFrom)
|
|
||||||
count, err := NodesCount(user.UserID, uint64(changedFrom), user.ClientUUID)
|
count, err := NodesCount(user.UserID, uint64(changedFrom), user.ClientUUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Log.Error("/sync/from_server/count", "error", err)
|
Log.Error("/sync/from_server/count", "error", err)
|
||||||
|
|
@ -341,7 +342,6 @@ func actionSyncToServer(w http.ResponseWriter, r *http.Request) { // {{{
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
responseData(w, map[string]any{
|
responseData(w, map[string]any{
|
||||||
"OK": true,
|
"OK": true,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,10 @@ html {
|
||||||
"tree files"
|
"tree files"
|
||||||
*/
|
*/
|
||||||
"tree blank"
|
"tree blank"
|
||||||
;
|
;
|
||||||
grid-template-columns: min-content 1fr;
|
grid-template-columns: min-content 1fr;
|
||||||
grid-template-rows:
|
grid-template-rows:
|
||||||
48px
|
48px 56px 48px min-content 1fr;
|
||||||
56px
|
|
||||||
48px
|
|
||||||
min-content
|
|
||||||
1fr;
|
|
||||||
|
|
||||||
|
|
||||||
@media only screen and (max-width: 600px) {
|
@media only screen and (max-width: 600px) {
|
||||||
|
|
@ -41,7 +37,7 @@ html {
|
||||||
"files"
|
"files"
|
||||||
*/
|
*/
|
||||||
"blank"
|
"blank"
|
||||||
;
|
;
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
|
||||||
#tree {
|
#tree {
|
||||||
|
|
@ -55,7 +51,8 @@ html {
|
||||||
display: grid;
|
display: grid;
|
||||||
padding: 16px 0px 16px 16px;
|
padding: 16px 0px 16px 16px;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
z-index: 100; /* Over crumbs shadow */
|
z-index: 100;
|
||||||
|
/* Over crumbs shadow */
|
||||||
border-left: 2px solid #333;
|
border-left: 2px solid #333;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
|
|
@ -90,13 +87,13 @@ html {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 24px min-content;
|
grid-template-columns: 24px min-content;
|
||||||
grid-template-rows:
|
grid-template-rows:
|
||||||
min-content
|
min-content 1fr;
|
||||||
1fr;
|
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
|
|
||||||
|
|
||||||
.expand-toggle {
|
.expand-toggle {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
|
@ -111,6 +108,7 @@ html {
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--color1);
|
color: var(--color1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
color: var(--color1);
|
color: var(--color1);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
@ -135,7 +133,7 @@ html {
|
||||||
padding: 16px 32px;
|
padding: 16px 32px;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 5px 5px 10px -5px rgba(0,0,0,0.75);
|
box-shadow: 5px 5px 10px -5px rgba(0, 0, 0, 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
#crumbs {
|
#crumbs {
|
||||||
|
|
@ -158,6 +156,7 @@ html {
|
||||||
&.node-modified {
|
&.node-modified {
|
||||||
background-color: var(--color1);
|
background-color: var(--color1);
|
||||||
color: var(--color2);
|
color: var(--color2);
|
||||||
|
|
||||||
.crumb:after {
|
.crumb:after {
|
||||||
color: var(--color2);
|
color: var(--color2);
|
||||||
}
|
}
|
||||||
|
|
@ -184,6 +183,7 @@ html {
|
||||||
.crumb:last-child {
|
.crumb:last-child {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.crumb:last-child:after {
|
.crumb:last-child:after {
|
||||||
content: '';
|
content: '';
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
|
|
@ -194,55 +194,64 @@ html {
|
||||||
}
|
}
|
||||||
|
|
||||||
#sync-progress {
|
#sync-progress {
|
||||||
|
--radius: 8px;
|
||||||
|
|
||||||
grid-area: sync;
|
grid-area: sync;
|
||||||
display: grid;
|
display: grid;
|
||||||
justify-items: center;
|
justify-items: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 56px;
|
height: 56px;
|
||||||
position: relative;
|
|
||||||
|
|
||||||
progress {
|
.container {
|
||||||
width: 100%;
|
position: relative;
|
||||||
padding: 0 7px;
|
|
||||||
max-width: 900px;
|
progress {
|
||||||
height: 16px;
|
width: 900px;
|
||||||
border-radius: 4px;
|
padding: 0 7px;
|
||||||
|
max-width: 900px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.count {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #888;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12pt;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress[value]::-webkit-progress-bar {
|
||||||
|
background-color: #eee;
|
||||||
|
box-shadow: 0 2px var(--radius) rgba(0, 0, 0, 0.25) inset;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress[value]::-moz-progress-bar {
|
||||||
|
background-color: #eee;
|
||||||
|
box-shadow: 0 2px var(--radius) rgba(0, 0, 0, 0.25) inset;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress[value]::-webkit-progress-value {
|
||||||
|
background: rgb(186, 95, 89);
|
||||||
|
background: linear-gradient(180deg, rgba(186, 95, 89, 1) 0%, rgba(254, 95, 85, 1) 50%, rgba(186, 95, 89, 1) 100%);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress[value]::-moz-progress-value {
|
||||||
|
background: rgb(186, 95, 89);
|
||||||
|
background: linear-gradient(180deg, rgba(186, 95, 89, 1) 0%, rgba(254, 95, 85, 1) 50%, rgba(186, 95, 89, 1) 100%);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progress[value]::-webkit-progress-bar {
|
|
||||||
background-color: #eee;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25) inset;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress[value]::-moz-progress-bar {
|
|
||||||
background-color: #eee;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25) inset;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress[value]::-webkit-progress-value {
|
|
||||||
background: rgb(186,95,89);
|
|
||||||
background: linear-gradient(180deg, rgba(186,95,89,1) 0%, rgba(254,95,85,1) 50%, rgba(186,95,89,1) 100%);
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: style the progress value for Firefox */
|
|
||||||
progress[value]::-moz-progress-value {
|
|
||||||
background: rgb(186,95,89);
|
|
||||||
background: linear-gradient(180deg, rgba(186,95,89,1) 0%, rgba(254,95,85,1) 50%, rgba(186,95,89,1) 100%);
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count {
|
|
||||||
width: min-content;
|
|
||||||
white-space: nowrap;
|
|
||||||
margin-top: 0px;
|
|
||||||
color: #888;
|
|
||||||
position: absolute;
|
|
||||||
top: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.hidden {
|
&.hidden {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
|
@ -270,6 +279,7 @@ html {
|
||||||
grid-area: content;
|
grid-area: content;
|
||||||
font-size: 1.0em;
|
font-size: 1.0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grow-wrap::after {
|
.grow-wrap::after {
|
||||||
/* Note the weird space! Needed to preventy jumpy behavior */
|
/* Note the weird space! Needed to preventy jumpy behavior */
|
||||||
content: attr(data-replicated-value) " ";
|
content: attr(data-replicated-value) " ";
|
||||||
|
|
@ -285,14 +295,16 @@ html {
|
||||||
/* Hidden from view, clicks, and screen readers */
|
/* Hidden from view, clicks, and screen readers */
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
.grow-wrap > textarea {
|
|
||||||
|
.grow-wrap>textarea {
|
||||||
/* You could leave this, but after a user resizes, then it ruins the auto sizing */
|
/* You could leave this, but after a user resizes, then it ruins the auto sizing */
|
||||||
resize: none;
|
resize: none;
|
||||||
|
|
||||||
/* Firefox shows scrollbar on growth, you can hide like this. */
|
/* Firefox shows scrollbar on growth, you can hide like this. */
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.grow-wrap > textarea,
|
|
||||||
|
.grow-wrap>textarea,
|
||||||
.grow-wrap::after {
|
.grow-wrap::after {
|
||||||
/* Identical styling required!! */
|
/* Identical styling required!! */
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
|
@ -301,6 +313,7 @@ html {
|
||||||
/* Place on top of each other */
|
/* Place on top of each other */
|
||||||
grid-area: 1 / 1 / 2 / 2;
|
grid-area: 1 / 1 / 2 / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
|
|
||||||
#node-content {
|
#node-content {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { ROOT_NODE } from 'node_store'
|
import { ROOT_NODE } from 'node_store'
|
||||||
import { TreeNative } from 'tree'
|
import { TreeNative } from 'tree'
|
||||||
import { NodeUINative, Node } from 'node'
|
import { NodeUINative, Node } from 'node'
|
||||||
|
import { SyncProgress } from 'sync'
|
||||||
|
|
||||||
export class App {
|
export class App {
|
||||||
constructor() {// {{{
|
constructor() {// {{{
|
||||||
|
|
@ -34,6 +35,9 @@ export class App {
|
||||||
document.getElementById('node-content')?.focus()
|
document.getElementById('node-content')?.focus()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const syncProgress = document.getElementById('sync-progress')
|
||||||
|
new SyncProgress(syncProgress)
|
||||||
|
|
||||||
window._sync = new Sync()
|
window._sync = new Sync()
|
||||||
window._sync.run()
|
window._sync.run()
|
||||||
}// }}}
|
}// }}}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ export class NodeUI extends Component {
|
||||||
${crumbDivs}
|
${crumbDivs}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<${SyncProgress} ref=${this.syncProgress} />
|
<div id="sync-progress"></div>
|
||||||
<div id="name">${node.get('Name')}</div>
|
<div id="name">${node.get('Name')}</div>
|
||||||
<${NodeContent} key=${node.UUID} node=${node} ref=${this.nodeContent} />
|
<${NodeContent} key=${node.UUID} node=${node} ref=${this.nodeContent} />
|
||||||
<div id="blank"></div>
|
<div id="blank"></div>
|
||||||
|
|
@ -156,8 +156,12 @@ export class NodeUI extends Component {
|
||||||
`
|
`
|
||||||
}//}}}
|
}//}}}
|
||||||
async componentDidMount() {//{{{
|
async componentDidMount() {//{{{
|
||||||
|
console.log('hum')
|
||||||
_notes2.current.goToNode(this.props.startNode.UUID, true)
|
_notes2.current.goToNode(this.props.startNode.UUID, true)
|
||||||
_notes2.current.tree.expandToTrunk(this.props.startNode)
|
_notes2.current.tree.expandToTrunk(this.props.startNode)
|
||||||
|
|
||||||
|
const syncProgressEl = document.getElementById('#sync-progress')
|
||||||
|
console.log(syncProgressEl)
|
||||||
}//}}}
|
}//}}}
|
||||||
setNode(node) {//{{{
|
setNode(node) {//{{{
|
||||||
this.nodeModified.value = false
|
this.nodeModified.value = false
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,11 @@
|
||||||
import { API } from 'api'
|
import { API } from 'api'
|
||||||
import { Node } from 'node'
|
import { Node } from 'node'
|
||||||
import { h, Component } from 'preact'
|
|
||||||
import htm from 'htm'
|
|
||||||
const html = htm.bind(h)
|
|
||||||
|
|
||||||
const SYNC_COUNT = 1
|
|
||||||
const SYNC_HANDLED = 2
|
|
||||||
const SYNC_DONE = 3
|
|
||||||
|
|
||||||
export class Sync {
|
export class Sync {
|
||||||
constructor() {//{{{
|
constructor() {//{{{
|
||||||
this.listeners = []
|
this.listeners = []
|
||||||
this.messagesReceived = []
|
this.messagesReceived = []
|
||||||
}//}}}
|
}//}}}
|
||||||
addListener(fn, runMessageQueue) {//{{{
|
|
||||||
// Some handlers won't be added until a time after sync messages have been added to the queue.
|
|
||||||
// This is an opportunity for the handler to receive the old messages in order.
|
|
||||||
if (runMessageQueue)
|
|
||||||
for (const msg of this.messagesReceived)
|
|
||||||
fn(msg)
|
|
||||||
this.listeners.push(fn)
|
|
||||||
}//}}}
|
|
||||||
pushMessage(msg) {//{{{
|
|
||||||
this.messagesReceived.push(msg)
|
|
||||||
for (const fn of this.listeners)
|
|
||||||
fn(msg)
|
|
||||||
}//}}}
|
|
||||||
|
|
||||||
async run() {//{{{
|
async run() {//{{{
|
||||||
try {
|
try {
|
||||||
|
|
@ -38,8 +18,8 @@ export class Sync {
|
||||||
|
|
||||||
let nodeCount = await this.getNodeCount(oldMax)
|
let nodeCount = await this.getNodeCount(oldMax)
|
||||||
nodeCount += await nodeStore.sendQueue.count()
|
nodeCount += await nodeStore.sendQueue.count()
|
||||||
const msg = { op: SYNC_COUNT, count: nodeCount }
|
|
||||||
this.pushMessage(msg)
|
_mbus.dispatch('SYNC_COUNT', { count: nodeCount })
|
||||||
|
|
||||||
await this.nodesFromServer(oldMax)
|
await this.nodesFromServer(oldMax)
|
||||||
.then(durationNodes => {
|
.then(durationNodes => {
|
||||||
|
|
@ -49,7 +29,7 @@ export class Sync {
|
||||||
|
|
||||||
await this.nodesToServer()
|
await this.nodesToServer()
|
||||||
} finally {
|
} finally {
|
||||||
this.pushMessage({ op: SYNC_DONE })
|
_mbus.dispatch('SYNC_DONE')
|
||||||
}
|
}
|
||||||
}//}}}
|
}//}}}
|
||||||
async getNodeCount(oldMax) {//{{{
|
async getNodeCount(oldMax) {//{{{
|
||||||
|
|
@ -60,6 +40,7 @@ export class Sync {
|
||||||
async nodesFromServer(oldMax) {//{{{
|
async nodesFromServer(oldMax) {//{{{
|
||||||
const syncStart = Date.now()
|
const syncStart = Date.now()
|
||||||
let syncEnd
|
let syncEnd
|
||||||
|
let handled = 0
|
||||||
try {
|
try {
|
||||||
let currMax = oldMax
|
let currMax = oldMax
|
||||||
let offset = 0
|
let offset = 0
|
||||||
|
|
@ -86,9 +67,14 @@ export class Sync {
|
||||||
for (const i in res.Nodes) {
|
for (const i in res.Nodes) {
|
||||||
backendNode = new Node(res.Nodes[i], -1)
|
backendNode = new Node(res.Nodes[i], -1)
|
||||||
await window._sync.handleNode(backendNode)
|
await window._sync.handleNode(backendNode)
|
||||||
|
|
||||||
|
handled++
|
||||||
|
if (handled % 100 === 0)
|
||||||
|
_mbus.dispatch('SYNC_HANDLED', { handled })
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (res.Continue)
|
} while (res.Continue)
|
||||||
|
_mbus.dispatch('SYNC_HANDLED', { handled })
|
||||||
|
|
||||||
nodeStore.setAppState('latest_sync_node', currMax)
|
nodeStore.setAppState('latest_sync_node', currMax)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -130,7 +116,7 @@ export class Sync {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
} finally {
|
} finally {
|
||||||
this.pushMessage({ op: SYNC_HANDLED, count: 1 })
|
//_mbus.dispatch('SYNC_HANDLED', { count: 1 })
|
||||||
}
|
}
|
||||||
}//}}}
|
}//}}}
|
||||||
async nodesToServer() {//{{{
|
async nodesToServer() {//{{{
|
||||||
|
|
@ -157,7 +143,7 @@ export class Sync {
|
||||||
// Nodes are archived on server and can now be deleted from the send queue.
|
// Nodes are archived on server and can now be deleted from the send queue.
|
||||||
const keys = nodesToSend.map(node => node.ClientSequence)
|
const keys = nodesToSend.map(node => node.ClientSequence)
|
||||||
await nodeStore.sendQueue.delete(keys)
|
await nodeStore.sendQueue.delete(keys)
|
||||||
this.pushMessage({ op: SYNC_HANDLED, count: nodesToSend.length })
|
_mbus.dispatch('SYNC_UPLOADED', { count: nodesToSend.length })
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.trace(e)
|
console.trace(e)
|
||||||
|
|
@ -168,11 +154,28 @@ export class Sync {
|
||||||
}//}}}
|
}//}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SyncProgress extends Component {
|
export class SyncProgress {
|
||||||
constructor() {//{{{
|
constructor(parentEl) {//{{{
|
||||||
super()
|
|
||||||
this.reset()
|
this.reset()
|
||||||
|
_mbus.subscribe('SYNC_COUNT', event => this.progressHandler(event))
|
||||||
|
_mbus.subscribe('SYNC_HANDLED', event => this.progressHandler(event))
|
||||||
|
_mbus.subscribe('SYNC_DONE', event => this.progressHandler(event))
|
||||||
|
|
||||||
|
this.el = this.createElements()
|
||||||
|
parentEl.replaceChildren(this.el)
|
||||||
}//}}}
|
}//}}}
|
||||||
|
createElements() {
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.classList.add('container')
|
||||||
|
div.innerHTML = `
|
||||||
|
<progress min=0 max=137 value=0></progress>
|
||||||
|
<div class="count">0 / 0</div>
|
||||||
|
`
|
||||||
|
|
||||||
|
this.elProgress = div.querySelector('progress')
|
||||||
|
this.elCount = div.querySelector('.count')
|
||||||
|
return div
|
||||||
|
}
|
||||||
reset() {//{{{
|
reset() {//{{{
|
||||||
this.forceUpdateRequest = null
|
this.forceUpdateRequest = null
|
||||||
this.state = {
|
this.state = {
|
||||||
|
|
@ -182,9 +185,6 @@ export class SyncProgress extends Component {
|
||||||
}
|
}
|
||||||
document.getElementById('sync-progress')?.classList.remove('hidden')
|
document.getElementById('sync-progress')?.classList.remove('hidden')
|
||||||
}//}}}
|
}//}}}
|
||||||
componentDidMount() {//{{{
|
|
||||||
window._sync.addListener(msg => this.progressHandler(msg), true)
|
|
||||||
}//}}}
|
|
||||||
getSnapshotBeforeUpdate(_, prevState) {//{{{
|
getSnapshotBeforeUpdate(_, prevState) {//{{{
|
||||||
if (!prevState.syncedDone && this.state.syncedDone)
|
if (!prevState.syncedDone && this.state.syncedDone)
|
||||||
setTimeout(() => document.getElementById('sync-progress')?.classList.add('hidden'), 750)
|
setTimeout(() => document.getElementById('sync-progress')?.classList.add('hidden'), 750)
|
||||||
|
|
@ -202,19 +202,22 @@ export class SyncProgress extends Component {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}//}}}
|
}//}}}
|
||||||
progressHandler(msg) {//{{{
|
progressHandler(event) {//{{{
|
||||||
switch (msg.op) {
|
const eventData = event.detail.data
|
||||||
case SYNC_COUNT:
|
switch (event.type) {
|
||||||
this.setState({ nodesToSync: msg.count })
|
case 'SYNC_COUNT':
|
||||||
|
console.log(eventData.count)
|
||||||
|
this.state.nodesToSync = eventData.count
|
||||||
break
|
break
|
||||||
|
|
||||||
case SYNC_HANDLED:
|
case 'SYNC_HANDLED':
|
||||||
this.state.nodesSynced += msg.count
|
console.log('sync handled')
|
||||||
|
this.state.nodesSynced = eventData.handled
|
||||||
break
|
break
|
||||||
|
|
||||||
case SYNC_DONE:
|
case 'SYNC_DONE':
|
||||||
// Hides the progress bar.
|
// Hides the progress bar.
|
||||||
this.setState({ syncedDone: true })
|
this.state.syncedDone = true
|
||||||
|
|
||||||
// Don't update anything if nothing was synced.
|
// Don't update anything if nothing was synced.
|
||||||
if (this.state.nodesSynced === 0)
|
if (this.state.nodesSynced === 0)
|
||||||
|
|
@ -227,17 +230,19 @@ export class SyncProgress extends Component {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
this.render()
|
||||||
}//}}}
|
}//}}}
|
||||||
render(_, { nodesToSync, nodesSynced }) {//{{{
|
render() {//{{{
|
||||||
|
console.log('render', this.state.nodesToSync)
|
||||||
|
this.elProgress.max = this.state.nodesToSync
|
||||||
|
this.elProgress.value = this.state.nodesSynced
|
||||||
|
this.elCount.innerText = `${this.state.nodesSynced} / ${this.state.nodesToSync}`
|
||||||
|
/*
|
||||||
if (nodesToSync === 0)
|
if (nodesToSync === 0)
|
||||||
return html`<div id="sync-progress"></div>`
|
return html`<div id="sync-progress"></div>`
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<div id="sync-progress">
|
|
||||||
<progress min=0 max=${nodesToSync} value=${nodesSynced}></progress>
|
|
||||||
<div class="count">${nodesSynced} / ${nodesToSync}</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}//}}}
|
}//}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,8 @@
|
||||||
<div id="tree" tabindex=0></div>
|
<div id="tree" tabindex=0></div>
|
||||||
<div id="crumbs"></div>
|
<div id="crumbs"></div>
|
||||||
<div id="sync-progress">
|
<div id="sync-progress">
|
||||||
<!--
|
|
||||||
<progress min=0 max=1 value=0></progress>
|
<progress min=0 max=1 value=0></progress>
|
||||||
<div class="count">0 / 1</div>
|
<div class="count">0 / 1</div>
|
||||||
-->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="note"></div>
|
<div id="note"></div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue