From 36d4b3848f0cd47b8807d159a2e0d29da5db1e9b Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Tue, 3 Jul 2018 12:33:31 +0200 Subject: [PATCH] Updates <3 --- js/client.ts | 2 +- js/load.ts | 5 +- js/main.ts | 1 - js/permission/PermissionManager.ts | 76 +++++++++++++++++++++++++----- js/ui/channel.ts | 9 ++-- js/ui/{ => frames}/ControlBar.ts | 4 +- js/ui/modal/ModalCreateChannel.ts | 71 ++++++++++++++++++++++++++-- js/ui/view.ts | 4 +- templates.html | 20 ++++---- 9 files changed, 156 insertions(+), 36 deletions(-) rename js/ui/{ => frames}/ControlBar.ts (98%) diff --git a/js/client.ts b/js/client.ts index f2d5b862..fa8e0ee4 100644 --- a/js/client.ts +++ b/js/client.ts @@ -8,7 +8,7 @@ /// /// /// -/// +/// enum DisconnectReason { REQUESTED, diff --git a/js/load.ts b/js/load.ts index a5199828..c7d56383 100644 --- a/js/load.ts +++ b/js/load.ts @@ -152,7 +152,9 @@ function loadDebug() { "js/ui/client.js", "js/ui/server.js", "js/ui/view.js", - "js/ui/ControlBar.js", + + "js/ui/frames/SelectedItemInfo.js", + "js/ui/frames/ControlBar.js", //Load permissions "js/permission/PermissionManager.js", @@ -176,7 +178,6 @@ function loadDebug() { "js/FileManager.js", "js/client.js", "js/chat.js", - "js/ui/frames/SelectedItemInfo.js", "js/Identity.js" ])).then(() => { awaitLoad(loadScripts(["js/main.js"])).then(() => { diff --git a/js/main.ts b/js/main.ts index c9f41170..eeb2502b 100644 --- a/js/main.ts +++ b/js/main.ts @@ -37,7 +37,6 @@ function main() { chat = new ChatBox($("#chat")); globalClient.setup(); - //globalClient.startConnection("localhost:19974"); //TODO remove only for testing if(!settings.static(Settings.KEY_DISABLE_UNLOAD_DIALOG, false)) { diff --git a/js/permission/PermissionManager.ts b/js/permission/PermissionManager.ts index 383fda0b..e5b5342b 100644 --- a/js/permission/PermissionManager.ts +++ b/js/permission/PermissionManager.ts @@ -293,7 +293,7 @@ class PermissionInfo { description: string; } -class GrantedPermission { +class PermissionValue { readonly type: PermissionInfo; value: number; @@ -303,10 +303,8 @@ class GrantedPermission { } granted(requiredValue: number, required: boolean = true) : boolean { - let result = false; - if(this.value == -2) - result = !required; - result = this.value == -1 || this.value >= requiredValue; + let result; + result = this.value == -1 || this.value >= requiredValue || (this.value == -2 && requiredValue == -2 && !required); log.trace(LogCategory.PERMISSIONS, "Test needed required: %o | %i | %o => " + result , this, requiredValue, required); return result; } @@ -316,7 +314,7 @@ class GrantedPermission { } } -class NeededGrantedPermission extends GrantedPermission { +class NeededPermissionValue extends PermissionValue { changeListener: ((newValue: number) => void)[] = []; constructor(type, value) { @@ -324,11 +322,20 @@ class NeededGrantedPermission extends GrantedPermission { } } +class ChannelPermissionRequest { + requested: number; + channel_id: number; + callback_success: ((_: PermissionValue[]) => any)[] = []; + callback_error: ((_: any) => any)[] = []; +} + class PermissionManager { readonly handle: TSClient; permissionList: PermissionInfo[] = []; - neededPermissions: NeededGrantedPermission[] = []; + neededPermissions: NeededPermissionValue[] = []; + + requests_channel_permissions: ChannelPermissionRequest[] = []; initializedListener: ((initialized: boolean) => void)[] = []; private _cacheNeededPermissions: any; @@ -338,6 +345,7 @@ class PermissionManager { this.handle.serverConnection.commandHandler["notifyclientneededpermissions"] = this.onNeededPermissions.bind(this); this.handle.serverConnection.commandHandler["notifypermissionlist"] = this.onPermissionList.bind(this); + this.handle.serverConnection.commandHandler["notifychannelpermlist"] = this.onChannelPermList.bind(this); } initialized() : boolean { @@ -384,7 +392,7 @@ class PermissionManager { let group = log.group(log.LogType.TRACE, LogCategory.PERMISSIONS, "Got " + json.length + " needed permissions."); for(let e of json) { - let entry: NeededGrantedPermission = undefined; + let entry: NeededPermissionValue = undefined; for(let p of copy) { if(p.type.id == e["permid"]) { entry = p; @@ -395,7 +403,7 @@ class PermissionManager { if(!entry) { let info = this.resolveInfo(e["permid"]); if(info) { - entry = new NeededGrantedPermission(info, -2); + entry = new NeededPermissionValue(info, -2); this.neededPermissions.push(entry); } else { log.warn(LogCategory.PERMISSIONS, "Could not resolve perm for id %s (%o|%o)", e["permid"], e, info); @@ -420,6 +428,32 @@ class PermissionManager { } } + private onChannelPermList(json) { + let permissions: PermissionValue[] = []; + let channelId: number = parseInt(json[0]["cid"]); + for(let element of json) { + let permission = this.resolveInfo(element["permid"]); + //TODO granted skipped and negated permissions + if(!permission) { + log.error(LogCategory.PERMISSIONS, "Failed to parse channel permission with id %o", element["permid"]); + continue; + } + + permissions.push(new PermissionValue(permission, element["permvalue"])); + } + + log.debug(LogCategory.PERMISSIONS, "Got channel permissions for channel %o", channelId); + for(let element of this.requests_channel_permissions) { + if(element.channel_id == channelId) { + for(let l of element.callback_success) + l(permissions); + this.requests_channel_permissions.remove(element); + return; + } + } + log.debug(LogCategory.PERMISSIONS, "Missing channel permission handle for requested channel id %o", channelId); + } + resolveInfo?(key: number | string | PermissionType) : PermissionInfo { for(let perm of this.permissionList) if(perm.id == key || perm.name == key) @@ -427,7 +461,27 @@ class PermissionManager { return undefined; } - neededPermission(key: number | string | PermissionType | PermissionInfo) : GrantedPermission { + requestChannelPermissions(channelId: number) : Promise { + return new Promise((resolve, reject) => { + let request: ChannelPermissionRequest; + for(let element of this.requests_channel_permissions) + if(element.requested + 1000 < Date.now() && request.channel_id == channelId) { + request = element; + break; + } + if(!request) { + request = new ChannelPermissionRequest(); + request.requested = Date.now(); + request.channel_id = channelId; + this.handle.serverConnection.sendCommand("channelpermlist", {"cid": channelId}); + this.requests_channel_permissions.push(request); + } + request.callback_error.push(reject); + request.callback_success.push(resolve); + }); + } + + neededPermission(key: number | string | PermissionType | PermissionInfo) : PermissionValue { for(let perm of this.neededPermissions) if(perm.type.id == key || perm.type.name == key || perm.type == key) return perm; @@ -437,7 +491,7 @@ class PermissionManager { log.warn(LogCategory.PERMISSIONS, "Requested needed permission with invalid key! (%o)", key); return undefined; } - let result = new NeededGrantedPermission(info, -2); + let result = new NeededPermissionValue(info, -2); this.neededPermissions.push(result); return result; diff --git a/js/ui/channel.ts b/js/ui/channel.ts index d8868209..d5809e3a 100644 --- a/js/ui/channel.ts +++ b/js/ui/channel.ts @@ -292,9 +292,7 @@ class ChannelEntry { type: MenuEntryType.ENTRY, icon: "client-channel_switch", name: "Switch to channel", - callback: () => { - this.joinChannel(); - } + callback: () => this.joinChannel() }, MenuEntry.HR(), { @@ -303,10 +301,13 @@ class ChannelEntry { name: "Edit channel", invalidPermission: !channelModify, callback: () => { - Modals.createChannelModal(this, undefined, (changes?: ChannelProperties) => { + Modals.createChannelModal(this, undefined, this.channelTree.client.permissions, (changes?: ChannelProperties) => { if(!changes) return; changes["cid"] = this.channelId; + this.channelTree.client.serverConnection.sendCommand("channeledit", changes); log.info(LogCategory.CHANNEL, "Changed channel properties of channel %s: %o", this.channelName(), changes); + }, permissions => { + //TODO }); } }, diff --git a/js/ui/ControlBar.ts b/js/ui/frames/ControlBar.ts similarity index 98% rename from js/ui/ControlBar.ts rename to js/ui/frames/ControlBar.ts index a7f31d22..e9bc3ec7 100644 --- a/js/ui/ControlBar.ts +++ b/js/ui/frames/ControlBar.ts @@ -1,5 +1,5 @@ -/// -/// +/// +/// /* client_output_hardware Value: '1' client_output_muted Value: '0' diff --git a/js/ui/modal/ModalCreateChannel.ts b/js/ui/modal/ModalCreateChannel.ts index d48845ac..1dc2a6dc 100644 --- a/js/ui/modal/ModalCreateChannel.ts +++ b/js/ui/modal/ModalCreateChannel.ts @@ -1,7 +1,7 @@ /// namespace Modals { - export function createChannelModal(channel: ChannelEntry | undefined, parent: ChannelEntry | undefined, callback: (ChannelProperties?: ChannelProperties) => void) { + export function createChannelModal(channel: ChannelEntry | undefined, parent: ChannelEntry | undefined, permissions: PermissionManager, callback: (ChannelProperties?: ChannelProperties) => void, callback_permission: (_: PermissionValue[]) => any) { let properties: ChannelProperties = { } as ChannelProperties; //The changes properties const modal = createModal({ header: channel ? "Edit channel" : "Create channel", @@ -32,10 +32,27 @@ namespace Modals { applyGeneralListener(properties, modal.htmlTag.find(".channel_general_properties"), modal.htmlTag.find(".button_ok"), !channel); applyStandardListener(properties, modal.htmlTag.find(".settings_standard"), modal.htmlTag.find(".button_ok"), parent, !channel); + applyPermissionListener(properties, modal.htmlTag.find(".settings_permissions"), modal.htmlTag.find(".button_ok"), permissions, channel); + let updated: PermissionValue[] = []; modal.htmlTag.find(".button_ok").click(() => { + modal.htmlTag.find(".settings_permissions").find("input[permission]").each((index, _element) => { + let element = $(_element); + if(!element.prop("changed")) return; + let permission = permissions.resolveInfo(element.attr("permission")); + if(!permission) { + log.error(LogCategory.PERMISSIONS, "Failed to resolve channel permission for name %o", element.attr("permission")); + element.prop("disabled", true); + return; + } + + updated.push(new PermissionValue(permission, element.val())); + }); + console.log("Updated permissions %o", updated); + }).click(() => { modal.close(); - callback(properties); + callback(properties); //First may create the channel + callback_permission(updated); }); modal.htmlTag.find(".button_cancel").click(() => { @@ -111,7 +128,8 @@ namespace Modals { .prop("disabled", !globalClient.permissions.neededPermission(create ? PermissionType.B_CHANNEL_CREATE_SEMI_PERMANENT : PermissionType.B_CHANNEL_MODIFY_MAKE_SEMI_PERMANENT).granted(1)); tag.find("input[name=\"channel_type\"][value=\"perm\"]") .prop("disabled", !globalClient.permissions.neededPermission(create ? PermissionType.B_CHANNEL_CREATE_PERMANENT : PermissionType.B_CHANNEL_MODIFY_MAKE_PERMANENT).granted(1)); - tag.find("input[name=\"channel_type\"]:not(:disabled)").last().prop("checked", true).trigger('change'); + if(create) + tag.find("input[name=\"channel_type\"]:not(:disabled)").last().prop("checked", true).trigger('change'); tag.find("input[name=\"channel_default\"]").change(function (this: HTMLInputElement) { console.log(this.checked); @@ -141,4 +159,51 @@ namespace Modals { }).prop("disabled", !globalClient.permissions.neededPermission(create ? PermissionType.B_CHANNEL_CREATE_WITH_SORTORDER : PermissionType.B_CHANNEL_MODIFY_SORTORDER).granted(1)); orderTag.find("option").last().prop("selected", true); } + + + function applyPermissionListener(properties: ChannelProperties, tag: JQuery, button: JQuery, permissions: PermissionManager, channel?: ChannelEntry) { + let apply_permissions = (channel_permissions: PermissionValue[]) => { + console.log("Got permissions: %o", channel_permissions); + let required_power = -2; + for(let cperm of channel_permissions) + if(cperm.type.name == PermissionType.I_CHANNEL_NEEDED_MODIFY_POWER) { + required_power = cperm.value; + return; + } + + tag.find("input[permission]").each((index, _element) => { + let element = $(_element); + let permission = permissions.resolveInfo(element.attr("permission")); + if(!permission) { + log.error(LogCategory.PERMISSIONS, "Failed to resolve channel permission for name %o", element.attr("permission")); + element.prop("disabled", true); + return; + } + + let old_value: number = 0; + element.on("click keyup", () => { + console.log("Permission triggered! %o", element.val() != old_value); + element.prop("changed", element.val() != old_value); + }); + + for(let cperm of channel_permissions) + if(cperm.type == permission) { + element.val(old_value = cperm.value); + return; + } + element.val(0); + }); + + if(!permissions.neededPermission(PermissionType.I_CHANNEL_MODIFY_POWER).granted(required_power, false)) { + tag.find("input[permission]").prop("enabled", false); //No permissions + } + }; + + if(channel) { + permissions.requestChannelPermissions(channel.getChannelId()).then(apply_permissions).catch((error) => { + tag.find("input[permission]").prop("enabled", false); + console.log(error); + }); + } else apply_permissions([]); + } } \ No newline at end of file diff --git a/js/ui/view.ts b/js/ui/view.ts index 69dc69cb..c3b0b3dd 100644 --- a/js/ui/view.ts +++ b/js/ui/view.ts @@ -255,11 +255,13 @@ class ChannelTree { } spawnCreateChannel(parent?: ChannelEntry) { - Modals.createChannelModal(undefined, parent, (properties?: ChannelProperties) => { + Modals.createChannelModal(undefined, parent, this.client.permissions, (properties?: ChannelProperties) => { if(!properties) return; properties["cpid"] = parent ? parent.channelId : 0; log.debug(LogCategory.CHANNEL, "Creating new channel with properties: %o", properties); this.client.serverConnection.sendCommand("channelcreate", properties); + }, permissions => { + //TODO }); } } \ No newline at end of file diff --git a/templates.html b/templates.html index 34c6c44f..1b06579f 100644 --- a/templates.html +++ b/templates.html @@ -45,9 +45,9 @@
Channel Type
-
Temporary
-
Semi-Permanent
-
Permanent
+
Temporary
+
Semi-Permanent
+
Permanent

Default Channel
@@ -74,16 +74,15 @@ Permissions - TODO Implement!