parent
43b6ac9501
commit
863fe23347
@ -325,7 +325,7 @@
|
|||||||
<span ng-switch-when="idle"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs" aria-label="{{'Up to Date' | translate}}"><i class="fas fa-fw fa-check"></i></span></span>
|
<span ng-switch-when="idle"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs" aria-label="{{'Up to Date' | translate}}"><i class="fas fa-fw fa-check"></i></span></span>
|
||||||
<span ng-switch-when="syncing">
|
<span ng-switch-when="syncing">
|
||||||
<span class="hidden-xs" translate>Syncing</span>
|
<span class="hidden-xs" translate>Syncing</span>
|
||||||
<span ng-show="syncRemaining(folder.id)">({{syncPercentage(folder.id) | percent}}, {{syncRemaining(folder.id) | binary}}B)</span>
|
<span>({{syncPercentage(folder.id) | percent}}, {{model[folder.id].needBytes | binary}}B)</span>
|
||||||
</span>
|
</span>
|
||||||
<span ng-switch-when="outofsync"><span class="hidden-xs" translate>Out of Sync</span><span class="visible-xs" aria-label="{{'Out of Sync' | translate}}"><i class="fas fa-fw fa-exclamation-circle"></i></span></span>
|
<span ng-switch-when="outofsync"><span class="hidden-xs" translate>Out of Sync</span><span class="visible-xs" aria-label="{{'Out of Sync' | translate}}"><i class="fas fa-fw fa-exclamation-circle"></i></span></span>
|
||||||
<span ng-switch-when="faileditems"><span class="hidden-xs" translate>Failed Items</span><span class="visible-xs" aria-label="{{'Failed Items' | translate}}"><i class="fas fa-fw fa-exclamation-circle"></i></span></span>
|
<span ng-switch-when="faileditems"><span class="hidden-xs" translate>Failed Items</span><span class="visible-xs" aria-label="{{'Failed Items' | translate}}"><i class="fas fa-fw fa-exclamation-circle"></i></span></span>
|
||||||
|
|||||||
@ -816,22 +816,6 @@ angular.module('syncthing.core')
|
|||||||
return Math.floor(pct);
|
return Math.floor(pct);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.syncRemaining = function (folder) {
|
|
||||||
// Remaining sync bytes
|
|
||||||
if (typeof $scope.model[folder] === 'undefined') {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ($scope.model[folder].globalBytes === 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bytes = $scope.model[folder].globalBytes - $scope.model[folder].inSyncBytes;
|
|
||||||
if (isNaN(bytes) || bytes < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.scanPercentage = function (folder) {
|
$scope.scanPercentage = function (folder) {
|
||||||
if (!$scope.scanProgress[folder]) {
|
if (!$scope.scanProgress[folder]) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@ -149,7 +149,7 @@ func (c *folderSummaryService) OnEventRequest() {
|
|||||||
// listenForUpdates subscribes to the event bus and makes note of folders that
|
// listenForUpdates subscribes to the event bus and makes note of folders that
|
||||||
// need their data recalculated.
|
// need their data recalculated.
|
||||||
func (c *folderSummaryService) listenForUpdates() {
|
func (c *folderSummaryService) listenForUpdates() {
|
||||||
sub := events.Default.Subscribe(events.LocalIndexUpdated | events.RemoteIndexUpdated | events.StateChanged | events.RemoteDownloadProgress | events.DeviceConnected | events.FolderWatchStateChanged)
|
sub := events.Default.Subscribe(events.LocalIndexUpdated | events.RemoteIndexUpdated | events.StateChanged | events.RemoteDownloadProgress | events.DeviceConnected | events.FolderWatchStateChanged | events.DownloadProgress)
|
||||||
defer events.Default.Unsubscribe(sub)
|
defer events.Default.Unsubscribe(sub)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -157,68 +157,84 @@ func (c *folderSummaryService) listenForUpdates() {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case ev := <-sub.C():
|
case ev := <-sub.C():
|
||||||
if ev.Type == events.DeviceConnected {
|
c.processUpdate(ev)
|
||||||
// When a device connects we schedule a refresh of all
|
|
||||||
// folders shared with that device.
|
|
||||||
|
|
||||||
data := ev.Data.(map[string]string)
|
|
||||||
deviceID, _ := protocol.DeviceIDFromString(data["id"])
|
|
||||||
|
|
||||||
c.foldersMut.Lock()
|
|
||||||
nextFolder:
|
|
||||||
for _, folder := range c.cfg.Folders() {
|
|
||||||
for _, dev := range folder.Devices {
|
|
||||||
if dev.DeviceID == deviceID {
|
|
||||||
c.folders[folder.ID] = struct{}{}
|
|
||||||
continue nextFolder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.foldersMut.Unlock()
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// The other events all have a "folder" attribute that they
|
|
||||||
// affect. Whenever the local or remote index is updated for a
|
|
||||||
// given folder we make a note of it.
|
|
||||||
|
|
||||||
data := ev.Data.(map[string]interface{})
|
|
||||||
folder := data["folder"].(string)
|
|
||||||
|
|
||||||
switch ev.Type {
|
|
||||||
case events.StateChanged:
|
|
||||||
if data["to"].(string) == "idle" && data["from"].(string) == "syncing" {
|
|
||||||
// The folder changed to idle from syncing. We should do an
|
|
||||||
// immediate refresh to update the GUI. The send to
|
|
||||||
// c.immediate must be nonblocking so that we can continue
|
|
||||||
// handling events.
|
|
||||||
|
|
||||||
c.foldersMut.Lock()
|
|
||||||
select {
|
|
||||||
case c.immediate <- folder:
|
|
||||||
delete(c.folders, folder)
|
|
||||||
default:
|
|
||||||
c.folders[folder] = struct{}{}
|
|
||||||
}
|
|
||||||
c.foldersMut.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
// This folder needs to be refreshed whenever we do the next
|
|
||||||
// refresh.
|
|
||||||
|
|
||||||
c.foldersMut.Lock()
|
|
||||||
c.folders[folder] = struct{}{}
|
|
||||||
c.foldersMut.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
case <-c.stop:
|
case <-c.stop:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *folderSummaryService) processUpdate(ev events.Event) {
|
||||||
|
var folder string
|
||||||
|
|
||||||
|
switch ev.Type {
|
||||||
|
case events.DeviceConnected:
|
||||||
|
// When a device connects we schedule a refresh of all
|
||||||
|
// folders shared with that device.
|
||||||
|
|
||||||
|
data := ev.Data.(map[string]string)
|
||||||
|
deviceID, _ := protocol.DeviceIDFromString(data["id"])
|
||||||
|
|
||||||
|
c.foldersMut.Lock()
|
||||||
|
nextFolder:
|
||||||
|
for _, folder := range c.cfg.Folders() {
|
||||||
|
for _, dev := range folder.Devices {
|
||||||
|
if dev.DeviceID == deviceID {
|
||||||
|
c.folders[folder.ID] = struct{}{}
|
||||||
|
continue nextFolder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.foldersMut.Unlock()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
case events.DownloadProgress:
|
||||||
|
data := ev.Data.(map[string]map[string]*pullerProgress)
|
||||||
|
c.foldersMut.Lock()
|
||||||
|
for folder := range data {
|
||||||
|
c.folders[folder] = struct{}{}
|
||||||
|
}
|
||||||
|
c.foldersMut.Unlock()
|
||||||
|
return
|
||||||
|
|
||||||
|
case events.StateChanged:
|
||||||
|
data := ev.Data.(map[string]interface{})
|
||||||
|
if !(data["to"].(string) == "idle" && data["from"].(string) == "syncing") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// The folder changed to idle from syncing. We should do an
|
||||||
|
// immediate refresh to update the GUI. The send to
|
||||||
|
// c.immediate must be nonblocking so that we can continue
|
||||||
|
// handling events.
|
||||||
|
|
||||||
|
folder = data["folder"].(string)
|
||||||
|
select {
|
||||||
|
case c.immediate <- folder:
|
||||||
|
c.foldersMut.Lock()
|
||||||
|
delete(c.folders, folder)
|
||||||
|
c.foldersMut.Unlock()
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
// Refresh whenever we do the next summary.
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// The other events all have a "folder" attribute that they
|
||||||
|
// affect. Whenever the local or remote index is updated for a
|
||||||
|
// given folder we make a note of it.
|
||||||
|
// This folder needs to be refreshed whenever we do the next
|
||||||
|
// refresh.
|
||||||
|
|
||||||
|
folder = ev.Data.(map[string]interface{})["folder"].(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.foldersMut.Lock()
|
||||||
|
c.folders[folder] = struct{}{}
|
||||||
|
c.foldersMut.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
// calculateSummaries periodically recalculates folder summaries and
|
// calculateSummaries periodically recalculates folder summaries and
|
||||||
// completion percentage, and sends the results on the event bus.
|
// completion percentage, and sends the results on the event bus.
|
||||||
func (c *folderSummaryService) calculateSummaries() {
|
func (c *folderSummaryService) calculateSummaries() {
|
||||||
|
|||||||
@ -801,7 +801,8 @@ func (m *model) ReceiveOnlyChangedSize(folder string) db.Counts {
|
|||||||
return db.Counts{}
|
return db.Counts{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NeedSize returns the number and total size of currently needed files.
|
// NeedSize returns the number of currently needed files and their total size
|
||||||
|
// minus the amount that has already been downloaded.
|
||||||
func (m *model) NeedSize(folder string) db.Counts {
|
func (m *model) NeedSize(folder string) db.Counts {
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
rf, ok := m.folderFiles[folder]
|
rf, ok := m.folderFiles[folder]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user