Repository: syncthing/syncthing
File: gui/default/syncthing/core/syncthingController.js (JavaScript)

Code before:
                name: arg.data.name,
                address: arg.data.address
            };
            console.log("rejected device:", arg.data.device, pendingDevice);

            $scope.pendingDevices[arg.data.device] = pendingDevice;
        });

        $scope.$on(Events.FOLDER_REJECTED, function (event, arg) {
            var offeringDevice = {
                time: arg.time,
                label: arg.data.folderLabel
            };
            console.log("rejected folder", arg.data.folder, "from device:", arg.data.device, offeringDevice);

            var pendingFolder = $scope.pendingFolders[arg.data.folder];
            if (pendingFolder === undefined) {
                pendingFolder = {
                    offeredBy: {}
                };
            }
            pendingFolder.offeredBy[arg.data.device] = offeringDevice;
            $scope.pendingFolders[arg.data.folder] = pendingFolder;
        });

        $scope.$on(Events.FOLDER_OFFER_CANCELLED, function (event, arg) {
            console.log("FolderOfferCancelled", arg);
            refreshCluster();
        });

        $scope.$on('ConfigLoaded', function () {
            if ($scope.config.options.urAccepted === 0) {
                // If usage reporting has been neither accepted nor declined,
                // we want to ask the user to make a choice. But we don't want
                // to bug them during initial setup, so we set a cookie with
                // the time of the first visit. When that cookie is present
                // and the time is more than four hours ago, we ask the
                // question.

                var firstVisit = document.cookie.replace(/(?:(?:^|.*;\s*)firstVisit\s*\=\s*([^;]*).*$)|^.*$/, "$1");
                if (!firstVisit) {
                    document.cookie = "firstVisit=" + Date.now() + ";max-age=" + 30 * 24 * 3600;
                } else {
                    if (+firstVisit < Date.now() - 4 * 3600 * 1000) {
                        $('#ur').modal();
                    }
                }
            }
        });

        $scope.$on(Events.CONFIG_SAVED, function (event, arg) {

Review comment (suggestion):
I don't think we should have a cancel event.

Effectively what we care about, is when the folder list is updated.
So far we used to rely on folder_rejected event/config_saved, but perhaps it now should be pending_folders_changed, or something.
If you really care what was added what was removed the "data" part of the event could contain that.

Otherwise, we'll get to silly territory of every action having a separate event, making it hard to subscribe to things you care about.

If you care about folders being added, you probably also care about them being removed, etc.

Code after:
                // Not enough information to update in place, just refresh it completely
                refreshCluster();
                return;
            }

            if (arg.data.added) {
                arg.data.added.forEach(function (rejected) {
                    var pendingDevice = {
                        time: arg.time,
                        name: rejected.name,
                        address: rejected.address
                    };
                    console.log("rejected device:", rejected.deviceID, pendingDevice);
                    $scope.pendingDevices[rejected.deviceID] = pendingDevice;
                });
            }

            if (arg.data.removed) {
                arg.data.removed.forEach(function (dev) {
                    console.log("no longer pending device:", dev.deviceID);
                    delete $scope.pendingDevices[dev.deviceID];
                });
            }
        });

        $scope.$on(Events.PENDING_FOLDERS_CHANGED, function (event, arg) {
            if (!(arg.data.added || arg.data.removed)) {
                // Not enough information to update in place, just refresh it completely
                refreshCluster();
                return;
            }

            if (arg.data.added) {
                arg.data.added.forEach(function (rejected) {
                    var offeringDevice = {
                        time: arg.time,
                        label: rejected.folderLabel
                    };
                    console.log("rejected folder", rejected.folderID, "from device:", rejected.deviceID, offeringDevice);

                    var pendingFolder = $scope.pendingFolders[rejected.folderID];
                    if (pendingFolder === undefined) {
                        pendingFolder = {
                            offeredBy: {}
                        };
                    }
                    pendingFolder.offeredBy[rejected.deviceID] = offeringDevice;
                    $scope.pendingFolders[rejected.folderID] = pendingFolder;
                });
            }