Skip to content

Commit

Permalink
Tidy up code of progress animation and make it linear; Tidy up code o…
Browse files Browse the repository at this point in the history
…f setting statusText for transfer notes
  • Loading branch information
schlagmichdoch committed Feb 17, 2024
1 parent d70f9d7 commit 50748ae
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 97 deletions.
28 changes: 14 additions & 14 deletions public/scripts/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ class Peer {
this._state = Peer.STATE_IDLE;
this._busy = false;

clearInterval(this._transferStatusInterval);
clearInterval(this._updateStatusTextInterval);

this._transferStatusInterval = null;
this._bytesTotal = 0;
Expand Down Expand Up @@ -646,23 +646,24 @@ class Peer {
}
}

_setTransferStatus(status) {
_updateStatusText() {
const secondsSinceStart = Math.round((Date.now() - this._timeStartTransferComplete) / 1000);

// Wait for 10s to only show info on longer transfers and to increase precision
if (secondsSinceStart < 10) return;

// mode: 0 -> speed, 1 -> time left, 2 -> receive/transfer
// mode: 0 -> speed, 1 -> time left, 2 -> receive/transfer (statusText = null)
const mode = Math.round((secondsSinceStart - 10) / 5) % 3;
let statusText = null;

if (mode === 0) {
status = this._getSpeedString();
statusText = this._getSpeedString();
}
else if (mode === 1) {
status = this._getTimeString();
statusText = this._getTimeString();
}

this._transferStatusString = status;
this._transferStatusText = statusText;
}

_calculateSpeedKbPerSecond() {
Expand All @@ -676,7 +677,7 @@ class Peer {
}

_calculateSecondsLeft() {
return Math.ceil(this._calculateBytesLeft() / this._calculateSpeedKbPerSecond() / 1000);
return Math.round(this._calculateBytesLeft() / this._calculateSpeedKbPerSecond() / 1000);
}

_getSpeedString() {
Expand Down Expand Up @@ -779,8 +780,8 @@ class Peer {

Events.fire('set-progress', {peerId: this._peerId, progress: 0, status: 'transfer'});

this._transferStatusString = 'transfer';
this._transferStatusInterval = setInterval(() => this._setTransferStatus('transfer'), 1000);
this._statusText = null;
this._updateStatusTextInterval = setInterval(() => this._updateStatusText(), 1000);

this._dequeueFile();
}
Expand Down Expand Up @@ -823,7 +824,7 @@ class Peer {

this._addLog(bytesReceivedTotal);

Events.fire('set-progress', {peerId: this._peerId, progress: progress, status: this._transferStatusString});
Events.fire('set-progress', {peerId: this._peerId, progress: progress, status: 'transfer', statusText: this._statusText});
}

_onFileReceiveComplete(message) {
Expand Down Expand Up @@ -918,16 +919,15 @@ class Peer {
this._byteLogs = [];
this._filesReceived = [];
this._acceptedRequest = this._pendingRequest;
this._lastProgress = 0;

this._bytesTotal = this._acceptedRequest.totalSize;
this._bytesReceivedFiles = 0;

Events.fire('set-progress', {peerId: this._peerId, progress: 0, status: 'receive'});

this._timeStartTransferComplete = Date.now();
this._transferStatusString = 'receive';
this._transferStatusInterval = setInterval(() => this._setTransferStatus('receive'), 1000);
this._statusText = null;
this._updateStatusTextInterval = setInterval(() => this._updateStatusText(), 1000);
}

this._sendMessage(message);
Expand Down Expand Up @@ -966,7 +966,7 @@ class Peer {

this._addLog(bytesReceivedTotal);

Events.fire('set-progress', {peerId: this._peerId, progress: progress, status: this._transferStatusString});
Events.fire('set-progress', {peerId: this._peerId, progress: progress, status: 'receive', statusText: this._statusText});
}

_sendResendRequest(offset) {
Expand Down
164 changes: 82 additions & 82 deletions public/scripts/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class PeersUI {
Events.on('peer-connecting', e => this._onPeerConnecting(e.detail));
Events.on('peer-disconnected', e => this._onPeerDisconnected(e.detail));
Events.on('peers', e => this._onPeers(e.detail));
Events.on('set-progress', e => this._onSetProgress(e.detail.peerId, e.detail.progress, e.detail.status));
Events.on('set-progress', e => this._onSetProgress(e.detail.peerId, e.detail.progress, e.detail.status, e.detail.statusText));

Events.on('drop', e => this._onDrop(e));
Events.on('keydown', e => this._onKeyDown(e));
Expand Down Expand Up @@ -185,12 +185,12 @@ class PeersUI {
})
}

_onSetProgress(peerId, progress, status) {
_onSetProgress(peerId, progress, status, statusText) {
const peerUI = this.peerUIs[peerId];

if (!peerUI) return;

peerUI.setProgressOrQueue(progress, status);
peerUI.queueProgressStatus(progress, status, statusText);
}

_onDrop(e) {
Expand Down Expand Up @@ -601,7 +601,7 @@ class PeerUI {
this._connected = true;

// on reconnect: reset status to saved status
this.setStatus(this._oldStatus);
this.queueProgressStatus(null, this._oldStatus);
this._oldStatus = null;

this._connectionHash = connectionHash;
Expand All @@ -612,7 +612,7 @@ class PeerUI {
// when connecting: / connection is lost: save old status
if (!this._oldStatus && this._currentStatus !== "connect") {
this._oldStatus = this._currentStatus;
this.setStatus("connect");
this.queueProgressStatus(null, "connect");
}

this._connectionHash = "";
Expand Down Expand Up @@ -688,71 +688,88 @@ class PeerUI {
$input.files = null; // reset input
}

setProgressOrQueue(progress, status) {
if (this._progressQueue.length > 0) {
if (progress) {
// if progress is higher than progress in queue -> overwrite in queue and cut queue at this position
for (let i = 0; i < this._progressQueue.length; i++) {
if (this._progressQueue[i].progress <= progress) {
this._progressQueue[i].progress = progress;
this._progressQueue[i].status = status;
this._progressQueue.splice(i + 1);
return;
}
}
queueProgressStatus(progress = null, status = null, statusText = null) {
// if progress is higher than progress in queue -> overwrite in queue and cut queue at this position
for (let i = 0; i < this._progressQueue.length; i++) {
if (this._progressQueue[i].progress <= progress && this._progressQueue[i].status === status) {
this._progressQueue[i] = {progress, status, statusText};
this._progressQueue.splice(i + 1);
return;
}
// add to queue
this._progressQueue.push({progress: progress, status: status});
return;
}
this._progressQueue.push({progress, status, statusText});

this.setProgress(progress, status);
// only dequeue if not already dequeuing
if (this._progressAnimatingTimeout) return;

this.dequeueProgressStatus();
}

setNextProgress() {
if (!this._progressQueue.length) return;
setNextProgressStatus() {
if (!this._progressQueue.length) {
// Queue is empty
this._progressAnimatingTimeout = null;
return;
}

setTimeout(() => {
let next = this._progressQueue.shift()
this.setProgress(next.progress, next.status);
}, 250); // 200 ms animation + buffer
// Queue is not empty -> set next progress
this.dequeueProgressStatus();
}

setProgress(progress, status) {
this.setStatus(status);
dequeueProgressStatus() {
clearTimeout(this._progressIdleTimeout);
clearTimeout(this._progressAnimatingTimeout);

if (progress === null) return;
let {progress, status, statusText} = this._progressQueue.shift();

// On complete status: set progress to 0 after 250ms and status to idle after 10s
if (status && (status.endsWith("-complete") || status === "error")) {
this._progressQueue.unshift({progress: 0});
this._progressIdleTimeout = setTimeout(() => this.setStatus("idle"), 10000);
}

// After animation has finished -> set next progress in queue
this._progressAnimatingTimeout = setTimeout(() => this.setNextProgressStatus(), 250); // 200 ms animation + buffer


// Only change status if explicitly set
if (status) {
this.setStatus(status, statusText);
}

// Only change progress if explicitly set and differs from current
if (progress === null || progress === this._currentProgress) return;

const progressSpillsOverHalf = this._currentProgress < 0.5 && 0.5 < progress; // 0.5 slips through
const progressSpillsOverFull = progress <= 0.5 && 0.5 <= this._currentProgress && this._currentProgress < 1;

// If spills over half: go to 0.5 first
// If spills over full: go to 1 first
if (progressSpillsOverHalf) {
this._progressQueue.unshift({progress: progress, status: status});
this.setProgress(0.5, status);
this._progressQueue.unshift({progress: 0.5}, {progress: progress});
this.dequeueProgressStatus();
return;
}
else if (progressSpillsOverFull) {
this._progressQueue.unshift({progress: progress, status: status});
this.setProgress(1, status);
this._progressQueue.unshift({progress: 1}, {progress: progress});
this.dequeueProgressStatus();
return;
}

if (progress === 0) {
this._currentProgress = 0;
this.$progress.classList.remove('animate');
this.$progress.classList.remove('over50');
this.$progress.style.setProperty('--progress', `rotate(${360 * progress}deg)`);
this.setNextProgress();
return;
// Clear progress after setting it to 1
if (progress === 1) {
this._progressQueue.unshift({progress: 0});
}

if (progress < this._currentProgress && status !== this._currentStatus) {
// reset progress
this._progressQueue.unshift({progress: progress, status: status});
this.setProgress(0, status);
// Set progress to 1 before setting to 0
if (progress === 0 && this._currentProgress !== 1) {
this._progressQueue.unshift({progress: 1});
this.dequeueProgressStatus();
return;
}

// under 0.5 -> remove second circle
// over 0.5 -> add second circle
if (progress < 0.5) {
this.$progress.classList.remove('animate');
this.$progress.classList.remove('over50');
Expand All @@ -764,62 +781,45 @@ class PeerUI {
this.$progress.classList.add('animate');
}

if (progress > this._currentProgress) {
this.$progress.classList.add('animate');
}
else {
// Do not animate when resetting progress from 1 to 0
if (progress === 0 && this._currentProgress === 1) {
this.$progress.classList.remove('animate');
}

if (progress === 1) {
// reset progress
this._progressQueue.unshift({progress: 0, status: status});
// If document is in background do not animate to prevent flickering on focus
if (!document.hasFocus()) {
this.$progress.classList.remove('animate');
}

this._currentProgress = progress;
this.$progress.style.setProperty('--progress', `rotate(${360 * progress}deg)`);

this.setNextProgress();
}

setStatus(status) {
if (status === this._currentStatus) return;

setStatus(status, statusText = null) {
this._currentStatus = status;

clearTimeout(this.statusTimeout);

if (status === 'idle') {
this.$el.removeAttribute('status');
this.$el.querySelector('.status').innerText = '';
return;
}

let statusText = {
"connect": Localization.getTranslation("peer-ui.connecting"),
"prepare": Localization.getTranslation("peer-ui.preparing"),
"transfer": Localization.getTranslation("peer-ui.transferring"),
"receive": Localization.getTranslation("peer-ui.receiving"),
"process": Localization.getTranslation("peer-ui.processing"),
"wait": Localization.getTranslation("peer-ui.waiting"),
"transfer-complete": Localization.getTranslation("peer-ui.transfer-complete"),
"receive-complete": Localization.getTranslation("peer-ui.receive-complete"),
"error": Localization.getTranslation("peer-ui.error")
}[status];

if (statusText) {
this.$el.setAttribute('status', status);
this.$el.querySelector('.status').innerText = statusText;
}
else {
this.$el.querySelector('.status').innerText = status;
if (!statusText) {
statusText = {
"connect": Localization.getTranslation("peer-ui.connecting"),
"prepare": Localization.getTranslation("peer-ui.preparing"),
"transfer": Localization.getTranslation("peer-ui.transferring"),
"receive": Localization.getTranslation("peer-ui.receiving"),
"process": Localization.getTranslation("peer-ui.processing"),
"wait": Localization.getTranslation("peer-ui.waiting"),
"transfer-complete": Localization.getTranslation("peer-ui.transfer-complete"),
"receive-complete": Localization.getTranslation("peer-ui.receive-complete"),
"error": Localization.getTranslation("peer-ui.error")
}[status];
}

if (status.endsWith("-complete") || status === "error") {
this.statusTimeout = setTimeout(() => {
this.setStatus("idle");
}, 10000);
}
this.$el.setAttribute('status', status);
this.$el.querySelector('.status').innerText = statusText;
}

_onDrop(e) {
Expand Down
2 changes: 1 addition & 1 deletion public/styles/styles-deferred.css
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ x-dialog .dialog-subheader {
}

.animate .circle {
transition: transform 200ms;
transition: transform 200ms linear;
}

.over50 {
Expand Down

0 comments on commit 50748ae

Please sign in to comment.