Updates <3

This commit is contained in:
WolverinDEV 2018-07-03 12:33:31 +02:00
parent abf32e114b
commit 36d4b3848f
9 changed files with 156 additions and 36 deletions

View file

@ -8,7 +8,7 @@
/// <reference path="FileManager.ts" />
/// <reference path="permission/PermissionManager.ts" />
/// <reference path="permission/GroupManager.ts" />
/// <reference path="ui/ControlBar.ts" />
/// <reference path="ui/frames/ControlBar.ts" />
enum DisconnectReason {
REQUESTED,

View file

@ -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(() => {

View file

@ -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)) {

View file

@ -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<PermissionValue[]> {
return new Promise<PermissionValue[]>((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;

View file

@ -292,9 +292,7 @@ class ChannelEntry {
type: MenuEntryType.ENTRY,
icon: "client-channel_switch",
name: "<b>Switch to channel</b>",
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
});
}
},

View file

@ -1,5 +1,5 @@
/// <reference path="../client.ts" />
/// <reference path="modal/ModalSettings.ts" />
/// <reference path="../../client.ts" />
/// <reference path="../modal/ModalSettings.ts" />
/*
client_output_hardware Value: '1'
client_output_muted Value: '0'

View file

@ -1,7 +1,7 @@
/// <reference path="../../utils/modal.ts" />
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([]);
}
}

View file

@ -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
});
}
}

View file

@ -45,9 +45,9 @@
<div style="vertical-align: center; margin: 20px;">
<a>Channel Type</a><br>
<fieldset style="border: gray solid; border-width: 2px; border-radius: 0px 6px 6px 6px;">
<div><input type="radio" name="channel_type" value="temp"> Temporary</div>
<div><input type="radio" name="channel_type" value="semi"> Semi-Permanent</div>
<div><input type="radio" name="channel_type" value="perm"> Permanent</div>
<div><input type="radio" name="channel_type" value="temp" {{if !channel_flag_semi_permanent && !channel_flag_permanent}}checked{{/if}}> Temporary</div>
<div><input type="radio" name="channel_type" value="semi" {{if channel_flag_semi_permanent}}checked{{/if}}> Semi-Permanent</div>
<div><input type="radio" name="channel_type" value="perm" {{if channel_flag_permanent}}checked{{/if}}> Permanent</div>
<hr style="width: 100%;">
<div><input type="checkbox" name="channel_default" id="default" value="def"> Default Channel</div>
</fieldset>
@ -74,16 +74,15 @@
<x-entry>
<x-tag>Permissions</x-tag>
<x-content>
<!--
<div style="display: flex; justify-content: space-evenly">
<div style="display: flex; justify-content: space-evenly" class="settings_permissions">
<div>
Regular needed powers:
<table class="channel_perm_tbl">
<tr><td class="key">Join:</td><td><input type="number" min="0" value="0" class="value"></td></tr>
<tr><td class="key">Subscribe:</td><td><input type="number" min="0" value="0" class="value"></td></tr>
<tr><td class="key">Desc. view:</td><td><input type="number" min="0" value="0" class="value"></td></tr>
<tr><td class="key">Modify:</td><td><input type="number" min="0" value="0" class="value"></td></tr>
<tr><td class="key">Delete:</td><td><input type="number" min="0" value="0" class="value"></td></tr>
<tr><td class="key">Join:</td><td><input type="number" min="0" value="0" class="value" permission="i_channel_needed_join_power"></td></tr>
<tr><td class="key">Subscribe:</td><td><input type="number" min="0" value="0" class="value" permission="i_channel_needed_subscribe_power"></td></tr>
<tr><td class="key">Desc. view:</td><td><input type="number" min="0" value="0" class="value" permission="i_channel_needed_description_view_power"></td></tr>
<tr><td class="key">Modify:</td><td><input type="number" min="0" value="0" class="value" permission="i_channel_needed_modify_power"></td></tr>
<tr><td class="key">Delete:</td><td><input type="number" min="0" value="0" class="value" permission="i_channel_needed_delete_power"></td></tr>
</table>
</div>
<div>
@ -97,7 +96,6 @@
</table>
</div>
</div>
-->
TODO Implement!
</x-content>
</x-entry>