construct/share/webapp/index.html

3056 lines
51 KiB
HTML

<!DOCTYPE html>
<html
lang="en"
>
<head>
<meta
charset="utf-8"
/>
<meta
http-equiv="x-ua-compatible"
content="ie=edge"
/>
<meta
name="description"
content="Matrix Construct"
/>
<link
rel="icon"
type="image/png"
href="favicon.ico"
/>
<link
rel="stylesheet" href="font-awesome.min.css"
/>
<link
rel="stylesheet" href="flat-ui.min.css"
/>
<link
rel="stylesheet" href="construct.css"
/>
<!--
for erry
-->
<title>
Matrix Construct
</title>
</head>
<body
ng-app="ircd"
ng-class="{ loaded: true }"
>
<!-- --------------------------------------------------------------------------
Matrix Construct Client
The document is specified as a set of Angular templates in <script> tags.
These templates are composed into the document by including other templates
in a tree. The root of the tree is the #charybdis <div> at the end of the
<body>. The first template specified ('ircd') is the child content of that
root <div>.
'ircd' and 'charybdis' and 'client' are various namespace prefixes we reserve
for now.
Our HTML is styled specifically for working with Angular. The style is simple, easy to type
and mostly consistent without many special cases.
Tags without attributes are just like classic HTML:
<tag>
content
</tag>
Tags with attributes use newlines to give them more space, clarity and for easy addition and
modification of attributes; also helps the revision trackers (i.e git-blame):
<tag
ng-foo="foo"
>
--------------------------------------------------------------------------- -->
<script
id="ircd"
type="text/ng-template"
>
<div
id="charybdis_rooms"
class="rooms pane"
ng-show="mc.show['#charybdis_rooms']"
ng-include="'ircd_rooms'"
>
</div>
<div
id="charybdis_menu"
class="menu row wrap"
ng-controller="menu as menu"
ng-show="mc.show['#charybdis_menu']"
ng-include="'ircd_main_menu'"
>
</div>
<div
id="charybdis_login"
class="login_ pane"
ng-show="mc.show['#charybdis_login']"
ng-include="'charybdis_login'"
ircd-catch
>
</div>
</script>
<!-- --------------------------------------------------------------------------
Main Menu
--------------------------------------------------------------------------- -->
<script
id="ircd_main_menu"
type="text/ng-template"
>
<button
class="item column wrap"
ng-repeat="(name, item) in mc.main.menu"
ng-hide="item.hide == true"
ang-click="menu.toggle(mc.main.menu, name, $event);"
ng-class="
{
order: item.order,
sticky: item.sticky,
selected: menu.selected(mc.main.menu, name, item)
}"
>
<i
class="fa icon {{ item.icon }}"
aria-hidden="true"
>
</i>
<h2
class="name"
ng-bind="name"
>
</h2>
</button>
</script>
<script
id="ircd_menu_item"
type="text/ng-template"
>
<button
class="item"
ng-repeat="item in items"
ng-class="item.classes"
>
<i
class="fa icon"
ng-class="item.icon"
aria-hidden="true"
>
</i>
<h1
class="name"
>
{{ item.name }}
</h1>
</button>
</script>
<script
id="ircd_menu"
type="text/ng-template"
>
<form
class="menu"
ng-include="'ircd_menu_item'"
>
</form>
</script>
<!-- --------------------------------------------------------------------------
Main Login
--------------------------------------------------------------------------- -->
<script
id="charybdis_login"
type="text/ng-template"
>
<form
id="charybdis_login_form"
>
<h3>
<!-- <span class="matrix"><b>Z</b>emos <b>I</b>nter<b>A</b>ctive</span> -->
<span class="matrix"><b>M</b>atrix</span>
&nbsp;
<span class="construct"><b>C</b>onstruct</span>
</h3>
<input
name="username"
type="text"
ng-model="mc.local.user_id"
/>
<input
name="password"
type="password"
ng-model="mc.local.wasspord"
/>
<div
class="submit"
>
<button
name="login_"
type="submit"
class="submit button"
ng-click="mc.run()"
>
LOGIN
</button>
<button
name="register"
type="submit"
class="submit button"
ng-class="
{
disabled: mc.auth['m.register.user'].disabled,
}"
ng-click="mc.auth['m.register.user']() && mc.run()"
>
REGISTER
</button>
</div>
</form>
</script>
<!-- --------------------------------------------------------------------------
Rooms
--------------------------------------------------------------------------- -->
<script
id="ircd_rooms"
type="text/ng-template"
>
<div
class="room no-animate"
ng-repeat="room in mc.rooms.current.list"
ng-controller="room as this"
ng-include="'ircd_room'"
>
</div>
</script>
<!-- --------------------------------------------------------------------------
Room
--------------------------------------------------------------------------- -->
<script
id="ircd_room"
type="text/ng-template"
>
<label
for="{{room.id}}"
>
</label>
<div
class="event control bar"
ng-show="room.control.show_event_control"
ng-include="'ircd_room_control_events'"
ircd-catch
>
</div>
<div
class="detail control bar"
ng-show="room.control.show_detail"
ng-include="'ircd_room_control_detail'"
ircd-catch
>
</div>
<div
class="status frieze bar"
ng-if="room.content['mc.room.config']['show'].frieze !== false"
ng-include="'ircd_room_control_frieze'"
>
</div>
<div
class="main"
ng-include="'ircd_room_main'"
>
</div>
</script>
<script
id="ircd_room_main"
type="text/ng-template"
>
<div
class="content"
ng-include="'ircd_room_content'"
ircd-catch
>
</div>
<div
class="members"
ng-if="room.content['mc.room.config']['show'].members"
ng-controller="mc.room.membership.controller as members"
ng-include="'ircd_room_members'"
>
</div>
<form
class="event player menu column nowrap"
ng-show="room.control.show_event_control"
ng-include="'ircd_room_events_player'"
>
</form>
<div
class="explore"
ng-show="room.control.show_explore"
ng-include="'ircd_room_explore'"
>
</div>
</script>
<script
id="ircd_room_content"
type="text/ng-template"
>
<form
class="search"
ng-if="room.control.show_search"
ng-include="'ircd_room_search'"
>
</form>
<div
class="filler grow"
>
</div>
<div
class="events"
ng-controller="room.events as events"
ang-scroll="room.scroll.on($event)"
ng-include="'ircd_room_events'"
>
</div>
<form
class="input"
ng-if="room.content['mc.room.config']['show'].input !== false"
ng-show="room.control.show_main_input && room.control.mode == 'LIVE'"
ng-include="'ircd_room_input'"
>
</form>
</script>
<!-- Room Members -->
<script
id="ircd_room_members"
type="text/ng-template"
>
<div
class="menu"
ng-include="'ircd_room_members_menu'"
>
</div>
<div
class="list"
ang-scroll="members.scroll($event)"
ng-include="'ircd_room_members_list'"
ircd-catch
>
</div>
<form
class="search"
ng-include="'ircd_room_members_search'"
>
</form>
</script>
<script
id="ircd_room_members_menu"
type="text/ng-template"
>
<button
class="item"
ng-repeat="(name, item) in mc.room.membership.menu"
ng-show="item.show === true"
ng-click=
"
room.content['mc.room.config']['show']._members = members.filter != name;
members.filter = name;
members.info = undefined;
members.list = room.membership.sorted(name);
item.click(room, $event, members);
"
ng-class="
{
selected: members.filter == name
}">
<i
class="fa icon"
ng-class="item.icon"
aria-hidden="true"
>
</i>
<h5
class="name"
>
{{ item.name !== undefined? item.name : name.toUpperCase() }}
</h5>
</button>
</script>
<script
id="ircd_room_members_search"
type="text/ng-template"
>
<label
class="h6"
ng-hide="members.filter == 'invite'"
>
SEARCH MEMBERS
</label>
<label
class="h6"
ng-show="members.filter == 'invite'"
>
INVITE MEMBER
</label>
<input
name="pattern"
type="text"
autocomplete="off"
/>
</script>
<script
id="ircd_room_members_list"
type="text/ng-template"
>
<div
class="loading"
ng-show="members.loading === true"
>
<i
class="fa icon fa-spinner"
aria-hidden="true"
>
</i>
</div>
<div
class="member"
ng-repeat="member in members.list | limitTo:members.limit():members.begin"
ng-init="mxid = member.state_key"
ng-show="!members.info || members.info == mxid"
ng-include="'ircd_room_members_member'"
ng-class="
{
me: mxid == mc.my.mxid,
grow: members.info == mxid,
active: mc.users[mxid].currently_active === true,
inactive: mc.users[mxid].currently_active === false,
}">
</div>
</script>
<script
id="ircd_room_members_invite"
type="text/ng-template"
>
<i
class="icon fa fa-user-o"
aria-hidden="true"
>
</i>
<form
ng-submit="room.invite($event)"
>
<input
name="invite"
type="text"
autocomplete="ja"
onfocus="this.value=''"
onfocusout="this.value=''"
/>
<h6>
INVITE
</h6>
</form>
</script>
<script
id="ircd_room_members_member"
type="text/ng-template"
>
<div
class="head"
ng-click="togswap(members, 'info', mxid); $event.stopPropagation();"
ng-include="'ircd_room_members_member_head'"
ng-class="
{
selected: members.info == mxid,
}">
</div>
<div
class="info"
ng-if="members.info == mxid"
ng-include="'ircd_room_members_member_info'"
>
</div>
</script>
<script
id="ircd_room_members_member_head"
type="text/ng-template"
>
<i
class="icon fa"
aria-hidden="true"
ng-class="
{
'fa-user-o': room.typing.active[mxid] !== true,
'fa-keyboard-o': room.typing.active[mxid] === true,
}">
</i>
<h3
class="name"
>
{{ mc.m.sid(mxid) }}
</h3>
<h5
class="idle"
ng-if="mc.users[mxid].last_active_ago"
>
{{ mc.date.describe.elapsed(mc.users[mxid].last_active_ago, true); }}
</h5>
<div
class="grow"
>
</div>
<h6
class="domain"
>
{{ mc.m.domid(mxid) }}
</h6>
</script>
<script
id="ircd_room_members_member_info"
type="text/ng-template"
>
<div
class="mxid"
>
<p>
{{ mxid }}
</p>
</div>
<div
class="data"
ng-include="'ircd_room_members_member_info_data'"
>
</div>
<form
class="menu"
ng-include="'ircd_room_members_member_info_menu'"
>
</form>
<div
class="event"
ng-click="room.seek(member.event_id); $event.stopPropagation();"
>
<p>
{{ member.event_id }}
</p>
</div>
</script>
<script
id="ircd_room_members_member_info_data"
type="text/ng-template"
>
<div
class="attrs"
>
<div
class="attr"
ng-repeat="(name, attr) in mc.room.membership.controller.attributes"
ng-if="!attr.show || attr.show(room, member) !== false"
>
<h3>
{{ attr.name? attr.name(room, member) : name; }}
</h3>
<p>{{attr.value(room, member)}}</p>
</div>
</div>
<div
class="avatar"
>
<img
ng-if="member.content.avatar_url"
ng-src="{{mc.m.xc(member.content.avatar_url)}}"
onerror="this.style.display='none'"
target="_blank"
/>
</div>
</script>
<script
id="ircd_room_members_member_info_menu"
type="text/ng-template"
>
<button
class="item"
ng-repeat="(name, item) in mc.room.membership.member_info_menu"
ang-click="item.click($event, room, mxid)"
>
<i
class="fa icon {{ item.icon }}"
aria-hidden="true"
>
</i>
<h4
class="name"
>
{{ name }}
</h4>
</button>
</script>
<script
id="ircd_room_explore"
type="text/ng-template"
>
<div
class="control bar"
>
<i
class="refresh icon fa fa-refresh"
ng-click="$event.stopPropagation(); room.refresh_explore($event);"
aria-hidden="true"
>
</i>
</div>
<div
class="content"
>
</div>
</script>
<script
id="ircd_room_input_files"
type="text/ng-template"
>
<div
class="file"
ng-repeat="(name, file) in room.control.files"
ng-class="
{
start: file.ajax === undefined && file.reader.readyState == file.reader.EMPTY,
loading: file.ajax === undefined && file.reader.readyState == file.reader.LOADING,
loaded: file.ajax === undefined && file.reader.readyState == file.reader.DONE,
uploading: file.ajax !== undefined && file.progress.loaded != file.progress.total,
uploaded: file.ajax !== undefined && file.progress.loaded == file.progress.total,
failed: file.progress.type == 'error',
}">
<div
class="progress"
ng-if="file.progress.loaded != file.progress.total"
style="width: {{(file.progress.loaded / file.progress.total) * 100}}%;"
>
</div>
<div
class="error"
ng-if="file.progress.type == 'error'"
ng-init="error = new mc.error(file.error)"
ng-include="'ircd_error'"
>
</div>
<button
class="remove"
ng-click="mc.room.attach.cancel.call(room, $event, file); $event.stopPropagation();"
>
<i
class="fa icon fa-close"
aria-hidden="true"
>
</i>
</button>
<img
ng-if="file.opts.content.url !== undefined"
ng-src="{{mc.m.xc(file.opts.content.url)}}"
>
</img>
<h5
class="name"
ng-if="file.opts.content.url === undefined"
>
{{ file.name }}
</h5>
<h5
class="url"
ng-if="file.opts.content.url !== undefined"
>
{{ file.opts.content.url }}
</h5>
<div
class="status"
>
<p
class="bytes loaded"
ng-if="file.progress.loaded != file.progress.total"
>
{{ mc.space.describe.bytes(file.progress.loaded) }} of
</p>
<p
class="bytes total"
>
{{ mc.space.describe.bytes(file.progress.total) }}
</p>
<p
class="state"
ng-if="file.reader.readyState == file.reader.LOADING"
>
READING
</p>
<p
class="state"
ng-if="file.ajax === undefined && file.reader.readyState == file.reader.DONE"
>
READY
</p>
<p
class="state"
ng-if="file.ajax !== undefined && file.progress.type == 'loadend'"
>
UPLOADED
</p>
</div>
<div
class="text"
ng-if="file.opts.content.url !== undefined"
>
<h6
class="label"
>
TEXT
</h6>
<input
name="caption"
class="caption"
ng-model="file.opts.content.body"
/>
</div>
<button
class="post"
ng-if="file.opts.content.url !== undefined"
ang-click="mc.room.send.message.image.call(room, file.opts.content.url, file.opts.content.body); $event.stopPropagation()"
>
<i
class="fa icon fa-reply"
aria-hidden="true"
>
</i>
</button>
</div>
<div
class="summary"
ng-if="length(room.control.files) > 1"
ng-if="false"
>
</div>
</script>
<script
id="ircd_room_input_message"
type="text/ng-template"
>
<div
class="attach"
>
<i
class="reply icon fa fa-paperclip"
aria-hidden="true"
>
</i>
<input
name="file"
type="file"
class="file"
multiple
onchange=
"
let scope = angular.element(this).scope();
scope.room.attach(event);
scope.$apply();
" />
</div>
<textarea
name="message"
class="message"
autocomplete="off"
rows="1"
style="white-space: normal;"
ng-model="room.control.input"
ng-change="room.input.change($event)"
ng-keydown="room.input.keydown($event)"
ng-blur="room.input.blur($event)"
>
</textarea>
<button
name="submit"
type="submit"
class="submit"
ng-hide="empty(room.control.input)"
ng-click="room.input.submit($event)"
ng-class="
{
eval: room.control.evalmode || room.opts.local,
empty: empty(room.control.input),
}">
<i
class="reply icon fa fa-reply"
aria-hidden="true"
>
</i>
<span
ng-if="false"
ng-show="!room.control.evalmode && !room.opts.local"
>
SEND
</span>
<span
ng-show="room.control.evalmode || room.opts.local"
>
EVAL
</span>
</button>
</script>
<script
id="ircd_room_input"
type="text/ng-template"
>
<div
class="files"
ng-include="'ircd_room_input_files'"
>
</div>
<div
class="message"
ng-include="'ircd_room_input_message'"
>
</div>
</script>
<!-- Room Search -->
<script
id="ircd_room_search"
type="text/ng-template"
>
<div
class="row nowrap"
>
<div
class="column nowrap grow"
>
<input
name="query"
class="query"
autocomplete="off"
style="white-space: normal;"
ng-model="room.control.search_query"
ng-change="room.search($event);"
ng-model-options="{debounce: 250}"
/>
<h6
class="label"
>
SEARCH {{ room.content['m.room.name'][''].name }}
</h6>
</div>
<div
class="menu row nowrap"
ng-controller="menu as menu"
>
<button
class="item"
ng-repeat="(name, item) in room.search_menu"
ng-click="menu.toggle(room.search_menu, name, item, event);"
ng-class="
{
selected: menu.selected(room.search_menu, name, item),
}">
<i
class="fa icon {{item.icon}}"
aria-hidden="true"
>
</i>
<p
class="name"
>
{{ name }}
</p>
</button>
</div>
</div>
</script>
<script
id="ircd_room_events_player"
type="text/ng-template"
>
<button
ng-repeat="(name, item) in room.timeline_player"
ng-class="{ selected: room.control.mode == name }"
ng-click="item.click($event, room);"
class="item"
>
<i
class="fa icon"
ng-class="item.icon"
aria-hidden="true"
>
</i>
<h3
class="name"
>
{{ name }}
</h3>
</button>
</script>
<!-- Room Control -->
<script
id="ircd_room_control_events_state"
type="text/ng-template"
>
<h3>
STATE SLOT
</h3>
<div
class="slots column nowrap"
>
<div
class="slot row nowrap"
ng-repeat="(name, event) in room.state"
ng-class="
{
active: event.event_id !== undefined,
empty: event.event_id === undefined,
disabled: event.type === undefined && event.content === undefined,
}">
<h4>
{{ name.replace('m.room.','').replace('_', ' ').toUpperCase(); }}
</h4>
<input
class="id"
type="text"
ng-value="event.event_id"
/>
<p
class="sender"
>
{{event.sender}}
</p>
</div>
</div>
</script>
<script
id="ircd_room_control_events"
type="text/ng-template"
>
<div
class="row nowrap"
>
<div
class="state column nowrap"
ng-include="'ircd_room_control_events_state'"
>
</div>
<div
class="capstan column nowrap"
>
<div
class="head row nowrap"
>
<div
class="column nowrap"
>
<h3>
EVENT HORIZON
</h3>
<form>
<div
ng-repeat="(key, val) in room.timeline.horizon_event();"
ng-if="_typeof(val) != 'object'"
>
<h5>
{{ key }}
</h5>
<input
type="text"
ng-value="val"
/>
</div>
</form>
</div>
<div
class="column nowrap"
>
<h3>
TIMELINE
</h3>
<form>
<div
ng-repeat="(key, val) in room.timeline_stats()"
>
<h5>
{{ key }}
</h5>
<input
type="text"
ng-value="val"
/>
</div>
</form>
</div>
<div
class="column nowrap"
>
<h3>
CURRENT EVENT
</h3>
<form>
<div
ng-repeat="(key, val) in room.current_event()"
ng-if="_typeof(val) != 'object'"
>
<h5>
{{ key }}
</h5>
<input
type="text"
ng-value="val"
/>
</div>
</form>
</div>
</div>
<div
class="viewport column nowrap"
>
<h3>
VIEWPORT
</h3>
<form>
<h4>
DIVISION
</h4>
<div
ng-repeat="(key, val) in room.scroll.pct()"
>
<h5>
{{ key }}
</h5>
<input
type="text"
value="{{parseInt(val * 100)}}%"
/>
</div>
</form>
<form>
<h4>
LAST EVENT
</h4>
<div
ng-repeat="(key, val) in mc.get_rect(room.items().children().last())"
>
<h5>
{{ key }}
</h5>
<input
type="text"
ng-value="val"
/>
</div>
</form>
<form>
<h4>
SCROLL AREA
</h4>
<div
ng-repeat="(key, val) in mc.get_rect(room.items())"
>
<h5>
{{ key }}
</h5>
<input
type="text"
ng-value="val"
/>
</div>
</form>
</div>
</div>
</div>
<div
class="row"
>
<div
class="unknown"
ng-if="false"
>
<div
class="unknown"
>
</div>
</div>
</div>
</script>
<script
id="ircd_room_control_state_history_visibility"
type="text/ng-template"
>
<h3>
HISTORY VISIBILITY
</h3>
<form
class="menu"
>
<button
class="item"
ng-repeat="(name, item) in room.detail_scrollback"
ng-click="room.timeline.issue(
{
type: 'm.room.history_visibility',
content:
{
history_visibility: name,
},
},
{
element: $event.delegateTarget,
});"
ng-class="
{
selected: room.content['m.room.history_visibility'][''].history_visibility == name,
pending: room.pending['m.room.history_visibility'][''].history_visibility == name,
}">
<i
class="fa icon {{item.icon}}"
aria-hidden="true"
>
</i>
<h4
class="name"
>
{{ item.name? item.name : name.replace('_', ' ').toUpperCase() }}
</h4>
</button>
</form>
</script>
<script
id="ircd_room_control_state_join_rules"
type="text/ng-template"
>
<h3>
JOIN RULES
</h3>
<div
class="menu"
>
<button
class="item"
ng-repeat="(name, item) in room.detail_join_rules"
ng-click="room.timeline.issue(
{
type: 'm.room.join_rules',
content:
{
join_rule: name,
},
},
{
element: $event.delegateTarget,
});"
ng-class="
{
selected: room.content['m.room.join_rules'][''].join_rule == name,
pending: room.pending['m.room.join_rules'][''].join_rule == name,
}">
<i
class="fa icon {{item.icon}}"
aria-hidden="true"
>
</i>
<h4
class="name"
>
{{ name.replace('_', ' ').toUpperCase() }}
</h4>
</button>
</div>
</script>
<script
id="ircd_room_control_state_guest_access"
type="text/ng-template"
>
<h3>
GUEST ACCESS
</h3>
<div
class="menu row nowrap"
>
<button
class="item"
ng-repeat="(name, item) in room.detail_guest_access"
ng-click="room.timeline.issue(
{
type: 'm.room.guest_access',
content:
{
guest_access: name,
},
},
{
element: $event.delegateTarget,
});"
ng-class="
{
selected: room.content['m.room.guest_access'][''].guest_access == name,
pending: room.pending['m.room.guest_access'][''].guest_access == name,
}">
<i
class="fa icon"
ng-class="item.icon"
aria-hidden="true"
>
</i>
<h4
class="name"
>
{{ name.replace('_', ' ').toUpperCase() }}
</h4>
</button>
</div>
</script>
<script
id="ircd_room_control_power_levels"
type="text/ng-template"
>
<h3>
PRIVILEGE LEVELS
</h3>
<div
class="levels column nowrap"
>
<div
class="level"
ng-repeat="(name, level) in room.content['m.room.power_levels']['']"
ng-if="_typeof(level) === 'number'"
>
<h5
class="name"
>
{{ name.replace('_', ' ') }}
</h5>
<input
type="text"
class="number"
ng-value="level"
/>
</div>
</div>
</script>
<script
id="ircd_room_control_state_aliases_server_alias"
type="text/ng-template"
>
<h3
class="hashtag"
>
#
</h3>
<input
class="name"
type="text"
ng-value="alias"
ng-model="room.pending['m.room.aliases'][server].content.aliases[$index]"
ng-change="room.realias($event, server, $index);"
ng-model-options="{ updateOn: 'blur', getterSetter: false }"
/>
<h3
class="colon"
>
:
</h3>
<input
type="text"
class="server"
ng-value="server"
>
<div
class="progress"
>
</div>
</script>
<script
id="ircd_room_control_state_aliases"
type="text/ng-template"
>
<div
class="server"
ng-repeat="(server, event) in room.state['m.room.aliases']"
>
<div
class="alias"
ng-repeat="alias in event.content.aliases track by $index"
ng-include="'ircd_room_control_state_aliases_server_alias'"
ng-class="
{
pending: room.pending['m.room.aliases'][server] !== undefined,
}">
</div>
<div
class="alias"
ng-if="server == mc.my.server"
ng-include="'ircd_room_control_state_aliases_server_alias'"
ng-init=
"
server = mc.my.server;
$index = 'next';
">
</div>
</div>
<div
class="server"
ng-show="room.state['m.room.aliases'][mc.my.server] === undefined"
>
<div
class="alias"
ng-include="'ircd_room_control_state_aliases_server_alias'"
ng-init=
"
server = mc.my.server;
$index = 'next';
">
</div>
</div>
</script>
<script
id="ircd_room_control_state_name"
type="text/ng-template"
>
<input
name="name"
type="text"
autocomplete="off"
ng-value="room.content['m.room.name'][''].name"
ng-model="room.pending['m.room.name'].content.name"
ng-model-options="{ updateOn: 'blur', getterSetter: false }"
ng-change="room.restate($event, 'm.room.name');"
/>
<h6
class="label"
>
ROOM NAME
</h6>
<div
class="progress"
>
</div>
</script>
<script
id="ircd_room_control_ident"
type="text/ng-template"
>
<form
class="name"
ng-include="'ircd_room_control_state_name'"
ng-class="
{
pending: room.pending['m.room.name'] !== undefined,
}">
</form>
<form
class="aliases"
ng-include="'ircd_room_control_state_aliases'"
>
</form>
</script>
<script
id="ircd_room_control_rules"
type="text/ng-template"
>
<div
class="history"
ng-include="'ircd_room_control_state_history_visibility'"
>
</div>
<div
class="join_rules"
ng-include="'ircd_room_control_state_join_rules'"
>
</div>
<div
class="guest_access"
ng-include="'ircd_room_control_state_guest_access'"
>
</div>
</script>
<script
id="ircd_room_control_topic"
type="text/ng-template"
>
<textarea
name="topic"
style="white-space: normal"
>
{{
room.content['m.room.topic'][''].topic || 'topic'
}}
</textarea>
</script>
<script
id="ircd_room_control_detail"
type="text/ng-template"
>
<div
class="power_levels"
ng-include="'ircd_room_control_power_levels'"
>
</div>
<div
class="rules"
ng-include="'ircd_room_control_rules'"
>
</div>
<div
class="forms"
>
<div
class="ident"
ng-include="'ircd_room_control_ident'"
>
</div>
</div>
<div
class="topic"
ng-include="'ircd_room_control_topic'"
>
</div>
</script>
<script
id="ircd_room_control_frieze"
type="text/ng-template"
>
<div
class="name"
ng-click=
"
room.control.show_search = !room.control.show_search;
room.search($event);
$event.stopPropagation();
">
<h3
class="name"
>
{{ room.content['m.room.name'][''].name }}
</h3>
<button
ng-class="
{
selected: room.control.show_search,
}">
<i
class="search icon fa fa-search"
aria-hidden="true"
>
</i>
</button>
<h3
class="alias"
>
{{room.content['m.room.canonical_alias'][''].alias}}
</h3>
</div>
<div
class="id"
ng-if="room.content['mc.room.config']['show'].control !== false"
ng-dblclick="room.control.show_detail = !room.control.show_detail; $event.preventDefault();"
>
<button
ng-click="room.control.show_detail = !room.control.show_detail"
ng-class="
{
selected: room.control.show_detail,
}">
<i
class="detail icon fa fa-wrench pointer"
aria-hidden="true"
>
</i>
</button>
<h5
class="id"
>
{{ room.id }}
</h5>
</div>
<div
class="events"
ng-if="room.content['mc.room.config']['show'].player !== false"
ng-click=
"
room.control.show_event_control = !room.control.show_event_control;
room.control.show_event_timeline = room.control.show_event_control;
">
<button
ng-class="
{
selected: room.control.show_event_control,
}">
<i
class="members icon fa fa-gear pointer"
aria-hidden="true"
>
</i>
</button>
<div
class="timeline"
>
<p
class="count"
>
{{ room.timeline.length }}
</p>
<h5>
TL
</h5>
</div>
<div
class="state"
>
<p
class="count"
>
{{ room.timeline.stats().state }}
</p>
<h5>
ST
</h5>
</div>
<div
class="servers"
>
<p
class="count"
>
{{ room.timeline.servers().length }}
</p>
<h5>
HS
</h5>
</div>
<div
class="activity"
>
<i
class="mode icon fa"
aria-hidden="true"
ng-class="room.timeline_player[room.control.mode].icon"
>
</i>
<p
class="bytes down"
ng-if="mc.io.stats.recv.bytes"
>
{{mc.space.describe.bytes(mc.io.stats.recv.bytes)}}&#8595;
</p>
<i
class="activity icon fa fa-exchange"
aria-hidden="true"
ng-class="
{
activated: room.control.activity === true,
}">
</i>
<p
class="bytes up"
ng-if="mc.io.stats.send.bytes"
>
{{mc.space.describe.bytes(mc.io.stats.sent.bytes)}}&#8593;
</p>
<h5
ng-if="false"
class="timestamp"
>
{{ room.timeline[room.timeline.length - 1].origin_server_ts }}
</h5>
</div>
</div>
<div
class="members"
ng-if="!room.opts.local"
ng-click="toggle(room.content['mc.room.config']['show'], 'members')"
>
<button
ng-class="
{
selected: room.content['mc.room.config']['show'].members,
}">
<i
class="members icon fa fa-users"
aria-hidden="true"
>
</i>
</button>
<div
ng-repeat="(name, item) in mc.room.membership.frieze"
ng-if="item.show !== false && item.count(room)"
ng-click="item.click(room, $event); $event.stopPropagation();"
>
<p
class="count"
>
{{ item.count(room); }}
</p>
<h5>
{{ name }}
</h5>
</div>
</div>
<div
class="explore"
ng-click="room.toggle_explore($event);"
>
<i
class="explore fa icon arrow"
aria-hidden="true"
ng-class="
{
selected: room.control.show_explore,
'fa-angle-double-up': room.control.show_explore,
'fa-angle-double-right': !room.control.show_explore,
}">
</i>
<h4>
EXPLORE
</h4>
</div>
<div
class="menu_toggle"
ng-hide="mc.show['#charybdis_menu']"
ng-include="'ircd_room_control_frieze_charybdis_menu'"
>
</div>
</script>
<script
id="ircd_room_control_frieze_charybdis_menu"
type="text/ng-template"
>
<button
ng-click="mc.show['#charybdis_menu'] = !mc.show['#charybdis_menu'];"
ng-class="
{
selected: mc.show['#charybdis_menu']
}
">
<i
class="icon fa fa-bars"
aria-hidden="true"
>
</i>
</button>
</script>
<!-- Room Timeline -->
<script
id="ircd_room_events"
type="text/ng-template"
>
<div
ng-repeat="event in room.timeline"
ng-if="events.can_render(event, $index)"
ng-show="events.can_show(event, $index)"
class="event"
ng-class="
{
state: mc.event.is_state(event),
zoom: room.control.content.zoom == event.event_id,
grouping_start: events.is_grouping_start(event, $index),
grouping_end: events.is_grouping_end(event, $index),
show_info: room.control.show_event_info[event.event_id] !== undefined,
highlight: room.control.show_event_timeline && room.control.show_event_info[event.event_id] !== undefined,
}">
<label
for="{{event.event_id}}"
>
</label>
<div
class="timeline"
ng-if="room.control.show_event_timeline"
ng-click="togdel(room.control.show_event_info, event.event_id);"
ng-include="'ircd_room_event_timeline'"
>
</div>
<h4
class="sender"
ng-if="event.sender"
ng-include="'ircd_room_event_sender'"
ng-dblclick=
"
room.control.show_event_timeline = !room.control.show_event_timeline;
togdel(room.control.show_event_info, event.event_id);
$event.stopPropagation();
$event.preventDefault();
">
</h4>
<div
class="handler"
ng-if="handler_exists(event.type)"
ng-include="handler_path(event.type)"
ng-class="
{
selected: event.$mc$selected === true,
[this.dots_to_underscores(event.type)]: true,
}"
>
</div>
<div
class="handler unhandled"
ng-if="!handler_exists(event.type)"
ng-include="'ircd_room_event_unhandled'"
>
</div>
<h3
class="target"
ng-if="this.should_show_target(event)"
ng-include="'ircd_room_event_target'"
>
</h3>
<div
class="right"
>
<div
class="timestamp"
>
<p>
+{{ mc.date.describe.elapsed(mc.date.ago(event.origin_server_ts)); }}
</p>
</div>
</div>
</div>
<div
class="present event"
ng-include="'ircd_room_event_present'"
>
</div>
</script>
<script
id="ircd_room_event_timeline"
type="text/ng-template"
>
<h4
class="index"
ng-class="
{
'selected': room.control.show_event_info[event.event_id] === true
}">
{{ $index }}
</h4>
<div
class="info column nowrap"
ng-if="room.control.show_event_info[event.event_id] === true"
ng-click="$event.stopPropagation()"
>
<p
class="id"
>
{{ event.event_id }}
</p>
<form
class="explore2 event object"
ng-include="'ircd_object'"
ng-init="object = event;"
ng-controller="explore"
>
</form>
<form
class="menu row nowrap"
>
<button
class="item"
ng-repeat="(name, item) in room.event_menu"
ng-click="item.click($event, room)"
ng-class="
{
}">
<i
class="fa icon {{item.icon}}"
aria-hidden="true"
>
</i>
<h2
class="name"
>
{{ name }}
</h2>
</button>
</form>
</div>
</script>
<script
id="ircd_room_event_sender"
type="text/ng-template"
>
<span
class="open bracket"
>{{ this.open_bracket(event); }}</span>
<a
class="avatar"
ng-if="false"
ng-if="room.content['m.room.member'][event.sender].avatar_url"
ng-href="room.content['m.room.member'][event.sender].avatar_url"
>
<img
ng-src="room.content['m.room.member'][event.sender].avatar_url"
alt="{{ room.content['m.room.member'][event.sender].avatar_url }}"
target="_blank"
/>
</a>
<span
class="name"
ng-if="!this.sender_is_server(event)"
ng-class="
{
me: event.sender == mc.session.user_id,
}"
>
<span
ng-if="mc.users[event.sender].displayname"
>
{{ mc.users[event.sender].displayname }}
</span>
<span
ng-if="!mc.users[event.sender].displayname"
>
{{this.sender_sid(event.sender)}}
</span>
</span>
<span
class="domain"
>{{this.sender_domid(event.sender)}}</span>
<span
class="close bracket"
>{{this.close_bracket(event)}}</span>
</script>
<script
id="ircd_room_event_target"
type="text/ng-template"
>
<span
class="open bracket"
>&lt;</span>
<span
class="name"
>{{ mc.m.sid(event.target) }}</span>
&nbsp;
<span
class="domain"
>{{ event.domid(event.target) }}</span>
<span
class="close bracket"
>&gt;</span>
</script>
<script
id="ircd_room_event_present"
type="text/ng-template"
>
<div
class="typing"
>
<i
class="fa icon fa-keyboard-o"
ng-hide="empty(room.typing.active)"
>
</i>
<div
class="typer"
ng-repeat="(mxid, state) in room.typing.active"
ng-if="state === true"
>
<h1>
&lt;{{mc.m.sid(mxid)}}&gt;
</h1>
</div>
</div>
<div
class="receipts"
ng-if="!empty(room.current_event()['m.read'])"
>
<div
class="receipt"
ng-repeat="mxid in Object.keys(room.current_event()['m.read']) | reverse"
>
<h1>
{{ mc.m.sid(mxid) }}
</h1>
<p>
{{ mc.date.describe.since(room.current_event()['m.read'][mxid].ts, true) }}
</p>
</div>
<i
class="fa icon fa-eye"
>
</i>
</div>
</script>
<script
id="ircd_room_event_unhandled"
type="text/ng-template"
>
<div
class="changed"
>
<h1>
{{event.type}}
</h1>
<h4>
</h4>
</div>
<p
class="guru"
style="white-space: pre-wrap;"
>
{{ debug.stringify(event, 2) }}
</p>
</script>
<!-- --------------------------------------------------------------------------
Room Timeline Event Handlers
--------------------------------------------------------------------------- -->
<script
id="ircd_room_event__m_room_message"
type="text/ng-template"
>
<div
class="message"
ng-if="handler_exists(['m.room.message', event.content.msgtype])"
ng-include="handler_path(['m.room.message', event.content.msgtype])"
>
</div>
<div
class="message"
ng-if="!handler_exists(['m.room.message', event.content.msgtype])"
ng-include="handler_path(['m.room.message', '_unhandled'])"
>
</div>
</script>
<script
id="ircd_room_event__m_room_message__m_text"
type="text/ng-template"
>
<p
class="text"
>{{event.content.body}}</p>
</script>
<script
id="ircd_room_event__m_room_message__m_notice"
type="text/ng-template"
>
<div
class="notice"
>{{event.content.body}}</div>
</script>
<script
id="ircd_room_event__m_room_message__m_emote"
type="text/ng-template"
>
<p
class="emote"
>{{event.content.body}}</p>
</script>
<script
id="ircd_room_event__m_room_message__m_image"
type="text/ng-template"
>
<div
class="image"
ng-class="
{
zoom: room.control.content.zoom == event.event_id,
}">
<h6
class="label"
>
{{ event.content.body }}
</h6>
<img
ng-click="room.dom.zoom($event, event);"
ng-src="{{mc.m.xc(event.content.url)}}"
alt="{{event.content.body}}"
/>
</div>
</script>
<script
id="ircd_room_event__m_room_message__m_video"
type="text/ng-template"
>
<a
class="video"
ng-switch-when="m.video"
>
<img
ng-src="{{event.content.info.thumbnail_url}}"
ng-if="event.content.info.thumbnail_url !== undefined"
ng-show="event.content.info"
alt="{{event.content.body}}"
/>
<iframe
ng-if="false"
class="ytplayer"
type="text/html"
width="480"
height="260"
ng-src="{{mc.embed(event.content.url)}}"
frameborder="0"
>
</iframe>
</a>
</script>
<script
id="ircd_room_event__m_room_message___unhandled"
type="text/ng-template"
>
<p
class="default"
>
<span
ng-if="empty(event.content)"
>
Message content is empty.
</span>
<span
ng-if="!empty(event.content)"
>
<span
ng-if="!empty(event.content.msgtype)"
>
No msgtype in content.
</span>
<span
ng-if="!empty(event.content.msgtype)"
class="unhandled"
>
Unhandled msgtype: {{event.content.msgtype}}
</span>
</span>
</p>
</script>
<script
id="ircd_room_event__m_room_member"
type="text/ng-template"
>
<div
class="changed"
ng-class="event.content.membership"
>
<h1>
MEMBER
</h1>
<h2>
{{event.content.membership.toUpperCase()}}
</h2>
<h3
ng-switch on="event.content.membership"
>
<span
class="state_key"
ng-if="empty(event.content.displayname)"
>
{{mc.m.sid(event.state_key)}}
</span>
<span
class="displayname state_key"
ng-if="!empty(event.content.displayname)"
>
{{event.content.displayname}}
</span>
<span
ng-if="!empty(event.content.displayname)"
>
&nbsp;a.k.a.&nbsp;
</span>
<span
class="displayname state_key"
ng-if="!empty(event.content.displayname)"
>
{{mc.m.sid(event.state_key)}}
</span>
&nbsp;of&nbsp;
<span
class="domain"
>
{{mc.m.domid(event.state_key)}}
</span>
<!--
&nbsp;
<span ng-switch-when="join">joined</span>
<span ng-switch-when="leave">left</span>
<span ng-switch-when="invite">invited</span>
<span
class="default unhandled"
ng-switch-default
>
{{event.content.membership}}
</span>
-->
</h3>
</div>
</script>
<script
id="ircd_room_event__m_room_create"
type="text/ng-template"
>
<div
class="changed"
>
<h1>
CREATE
</h1>
<h4>
{{ room.id }}
</h4>
</div>
</script>
<script
id="ircd_room_event__m_room_power_levels"
type="text/ng-template"
>
<div
class="changed"
>
<h1>
POWER LEVELS
</h1>
<h4>
&nbsp;
</h4>
</div>
<div
class="new levels"
style="display: none"
>
<div
class="level"
ng-repeat="(name, level) in event.content"
ng-if="_typeof(level) === 'number'"
>
<h5
class="name"
>
{{ name }}
</h5>
<p>
{{ level }}
</p>
</div>
</div>
<div
class="old levels"
ng-if="false"
>
<div
class="level"
ng-repeat="(name, level) in event.content"
ng-if="_typeof(level) === 'number'"
>
<h4
class="name"
>
{{ name }}
</h4>
<p>
{{ level }}
</p>
</div>
</div>
</script>
<script
id="ircd_room_event__m_room_canonical_alias"
type="text/ng-template"
>
<div
class="changed"
>
<h1>
CANONICAL ALIAS
</h1>
<h4>
{{ event.content.alias }}
</h4>
</div>
</script>
<script
id="ircd_room_event__m_room_join_rules"
type="text/ng-template"
>
<div
class="changed"
>
<h1>
JOIN RULES
</h1>
<h4>
{{ event.content.join_rule }}
</h4>
</div>
<div
class="join_rules menu"
style="display: none"
>
<button
class="item"
ng-repeat="(name, item) in room.detail_join_rules"
ng-class="
{
selected: event.content.join_rule.toLowerCase() == name.toLowerCase(),
}">
<i
class="fa icon {{item.icon}}"
aria-hidden="true"
>
</i>
<h2
class="name"
>
{{ name }}
</h2>
</button>
</div>
</script>
<script
id="ircd_room_event__m_room_history_visibility"
type="text/ng-template"
>
<div
class="changed"
>
<h1>
HISTORY VISIBILITY
</h1>
<h4>
{{ event.content.history_visibility }}
</h4>
</div>
</script>
<script
id="ircd_room_event__m_room_guest_access"
type="text/ng-template"
>
<div
class="changed"
>
<h1>
GUEST ACCESS
</h1>
<h4>
{{ event.content.guest_access }}
</h4>
</div>
</script>
<script
id="ircd_room_event__m_room_aliases"
type="text/ng-template"
>
<div
class="changed"
>
<h1>
ALIASES
</h1>
<h4>
&nbsp;
</h4>
</div>
<div
class="aliases"
>
<h3
class="alias"
ng-repeat="alias in event.content.aliases"
>
{{ alias }}
</h3>
</div>
</script>
<script
id="ircd_room_event__m_room_name"
type="text/ng-template"
>
<div
class="changed"
>
<h1>
NAME
</h1>
<h4
class="name center"
ng-if="!room.name"
>
{{ event.content.name }}
</h4>
<h4
class="name center"
ng-if="room.name"
>
from <b>{{ room.name }}</b> to <b>{{ event.content.name }}</b>
</h4>
</div>
</script>
<script
id="ircd_room_event__m_room_topic"
type="text/ng-template"
>
<div
class="changed"
>
<h1
ng-click="event.$mc$selected =! event.$mc$selected"
>
TOPIC
</h1>
<h4
class="center"
>
{{ event.content.topic.split('\n')[0] }}
</h4>
</div>
<div
class="topic"
ng-if="event.$mc$selected === true"
>
<p>
{{ event.content.topic }}
</p>
</div>
</script>
<script
id="ircd_room_event__ircd_key"
type="text/ng-template"
>
<div
class="changed"
>
<h1
ng-click="event.$mc$selected =! event.$mc$selected"
>
SERVER KEY
</h1>
<h4>
{{event.content.server_name}}
</h4>
</div>
<form
class="explore2"
ng-if="event.$mc$selected === true"
ng-include="'ircd_object'"
ng-init="object = event.content;"
ng-controller="explore"
>
</form>
</script>
<script
id="ircd_room_event__mc_room"
type="text/ng-template"
>
<div
class="changed"
>
<h1
ng-click="event.$mc$selected =! event.$mc$selected"
>
ROOM
</h1>
<h2>
{{event.membership}}
</h2>
<h3>
{{event.state_key}}
</h3>
</div>
<div
class="item"
ng-init="room = mc.rooms[event.membership][event.state_key]"
ng-include="'ircd_rooms_list_item'"
>
</div>
</script>
<script
id="ircd_room_event__mc_menu"
type="text/ng-template"
>
<div
class="changed"
>
<h1
ng-click="event.$mc$selected =! event.$mc$selected"
>
MENU
</h1>
<h2
ng-click="event.$mc$selected =! event.$mc$selected"
>
{{ event.state_key }}
</h2>
</div>
<div
class="menu"
ng-if="handler_exists(['mc.menu', event.state_key])"
ng-include="handler_path(['mc.menu', event.state_key])"
ng-controller="menu as menu"
>
</div>
<div
class="unhandled"
ng-if="!handler_exists(['mc.menu', event.state_key])"
ng-include="'ircd_room_event___unhandled'"
>
</div>
</script>
<script
id="ircd_room_event__mc_room_config"
type="text/ng-template"
>
<div
class="changed"
>
<h1
ng-click="event.$mc$selected =! event.$mc$selected"
>
CONFIG
</h1>
<h2
ng-click="event.$mc$selected =! event.$mc$selected"
>
{{ event.state_key }}
</h2>
</div>
<div
class="config"
>
<button
class="item"
ng-repeat="(key, value) in event.content"
ng-click="event.content[key] =! event.content[key]"
>
<i
class="fa icon {{ item.icon }}"
aria-hidden="true"
>
</i>
<h2
class="name"
ng-bind="key"
>
</h2>
</div>
</div>
</script>
<script
id="ircd_room_event__mc_menu__rooms"
type="text/ng-template"
>
<button
class="item"
ng-repeat="(name, item) in mc.rooms.menu"
ng-hide="item.hide == true"
ang-click="menu.toggle(mc.rooms.menu, name, $event);"
ng-class="
{
order: item.order,
sticky: item.sticky,
selected: menu.selected(mc.rooms.menu, name, item)
}"
>
<i
class="fa icon {{ item.icon }}"
aria-hidden="true"
>
</i>
<h2
class="name"
ng-bind="name"
>
</h2>
</button>
</script>
<script
id="ircd_rooms_list_item"
type="text/ng-template"
>
<div
class="head"
ng-click="mc.rooms.info(room.id); mc.rooms.current.add(room.id); $event.stopPropagation();"
ng-include="'ircd_rooms_list_item_head'"
ng-class="
{
joined: mc.rooms.join[room.id] !== undefined,
invited: mc.rooms.invite[room.id] !== undefined,
}">
</div>
<div
class="info"
ng-if="mc.rooms.info.model == room.id;"
ng-include="'ircd_rooms_list_item_info'"
>
</div>
</script>
<script
id="ircd_rooms_list_item_head"
type="text/ng-template"
>
<div
class="left focus"
ng-click="mc.rooms.current.add(room.id); mc.rooms.info(room.id); $event.stopPropagation();"
ng-class="
{
'grow': mc.rooms.info.model == room.id,
joined: mc.rooms.join[room.id] !== undefined,
invited: mc.rooms.invite[room.id] !== undefined,
selected: mc.rooms.current(room.id) !== undefined,
}">
<i
class="left fa icon"
ng-class="
{
'fa-minus': mc.rooms.info.model == room.id,
'fa-plus-square': mc.rooms.info.model != room.id,
}">
</i>
</div>
<h3
class="right id grow"
ng-if="empty(room.content['m.room.name'][''].name) &&
empty(room.content['m.room.canonical_alias'][''].alias)"
>
{{ room.id }}
</h3>
<h3
class="right name grow"
ng-if="!empty(room.content['m.room.name'][''].name) &&
empty(room.content['m.room.canonical_alias'][''].alias)"
>
{{ room.content['m.room.name'][''].name }}
</h3>
<h3
class="right alias grow"
ng-if="!empty(room.content['m.room.canonical_alias'][''].alias)"
>
{{ room.content['m.room.canonical_alias'][''].alias }}
</h3>
<h4
class="right highlight_count"
ng-show="room.notifications.highlight_count"
>
{{ room.notifications.highlight_count }}
</h4>
<h4
class="right notification_count"
ng-show="room.notifications.notification_count"
>
{{ room.notifications.notification_count }}
</h4>
<h4
class="right member_count"
>
{{ room.membership.count('join') }}
</h4>
</script>
<script
id="ircd_rooms_list_item_info"
type="text/ng-template"
>
<div
class="name"
>
<h3>
{{ room.content['m.room.name'][''].name }}
</h3>
</div>
<div
class="id"
>
<h4>
{{ room.id }}
</h4>
</div>
<div
class="stats"
>
<div
class="joined"
ng-if="mc.rooms.join[room.id] !== undefined"
>
<h5
class="label"
>
JOINED
</h5>
<p>
{{mc.date.describe.since(mc.rooms.join[room.id].membership.me().origin_server_ts)}} ago
({{mc.date.local.pretty(mc.rooms.join[room.id].membership.me().origin_server_ts)}})
</p>
</div>
</div>
<form
class="menu"
ng-controller="menu as menu"
ng-include="'ircd_rooms_list_item_info_menu'"
>
</form>
</script>
<script
id="ircd_rooms_list_item_info_menu"
type="text/ng-template"
>
<button
type="submit"
class="item"
ng-repeat="(name, item) in mc.rooms.info.menu"
ng-hide="item.hide(room.id)"
ang-mousedown="menu.hold(mc.rooms.info.menu, name, $event, room.id);"
ang-mouseup="menu.hold(mc.rooms.info.menu, name, $event, room.id);"
ang-click="menu.toggle(mc.rooms.info.menu, name, $event, room.id);"
ng-class="item.classes"
>
<i
class="fa icon"
ng-class="item.icon"
aria-hidden="true"
>
</i>
<h3
class="name"
>
{{ name }}
</h3>
</button>
</script>
<!-- --------------------------------------------------------------------------
Util
--------------------------------------------------------------------------- -->
<script
id="ircd_error"
type="text/ng-template"
>
<div
class="error"
tabindex="0"
ng-controller="errors as this"
ng-dblclick="this.close($event);"
ng-blur="this.close($event);"
>
<div
class="header row nowrap"
>
<h4
ng-show="this.error.m.errcode && this.error.m.errcode != 'M_UNKNOWN'"
>
{{ mc.m.pretty_errcode(this.error.m.errcode); }}
</h4>
<h5
style="justify-content: flex-end; flex-grow: 1"
>
{{ this.error.status }} {{ this.error.name }}
</h5>
</div>
<div
class="message grow column nowrap"
>
<p
ng-show="this.error.m.error"
>
{{ this.error.m.error }}
</p>
<p
ng-show="this.error.message"
>
{{ this.error.message }}
</p>
</div>
<div
class="footer row nowrap"
>
<i
class="fa fa-code guru icon"
aria-hidden="true"
ng-show="this.error.stack || this.error.request_stack || this.error.response_stack"
ng-click="this.guru = !this.guru; $event.stopPropagation();"
>
</i>
<div
class="grow"
>
</div>
<i
class="fa fa-remove icon"
aria-hidden="true"
ng-hide="this.error.fatal"
ng-click="this.close($event);"
>
</i>
</div>
<div
class="guru column nowrap"
ng-show="this.guru === true"
ng-dblclick="this.guru = !this.guru; $event.stopPropagation();"
>
<i
class="fa fa-remove icon"
aria-hidden="true"
ng-click="this.guru = !this.guru; $event.stopPropagation();"
>
</i>
<div
class="stack row nowrap"
>
<div
class="stack column nowrap"
ng-if="this.error.request_stack"
>
<h3>
REQUEST STACK
</h3>
<p
class="request stack"
>{{this.error.request_stack}}</p>
</div>
<div
class="stack column nowrap"
ng-if="this.error.response_stack"
>
<h3>
RESPONSE STACK
</h3>
<p
class="response stack"
>{{this.error.response_stack}}</p>
</div>
<div
class="stack column nowrap"
ng-if="!this.error.response_stack && !error_request_stack && this.error.stack"
>
<h3>
EXCEPTION STACK
</h3>
<p
class="stack"
>{{this.error.stack}}</p>
</div>
</div>
<div
class="json column nowrap"
ng-if="this.error.m"
>
<p
class="json"
>{{debug.stringify(this.error.m, 3)}}</p>
</div>
</div>
</div>
</script>
<!--
Old jquery explorer
-->
<script
id="json_member"
type="text/ng-template"
>
<div
class="member"
>
<div
class="key"
>
<i
class="icon fa"
>
</i>
<p
class="name"
>
</p>
</div>
<div
class="value"
style="display: none"
>
</div>
</div>
</script>
<script
id="json_object"
type="text/ng-template"
>
<div
class="object"
>
</div>
</script>
<!--
New explorer
-->
<script
id="ircd_object"
type="text/ng-template"
>
<div
class="member"
ng-repeat="(key, val) in object"
>
<h5
class="key"
ng-if="_typeof(val) !== 'undefined'"
>
{{ key }}
</h5>
<input
type="text"
ng-value="val"
ng-if="_typeof(val) != 'object' && _typeof(val) != 'undefined'"
class="value"
/>
<div
class="object"
ng-include="'ircd_object'"
ng-if="_typeof(val) == 'object'"
ng-init="object = val;"
>
</div>
</div>
</script>
<!-- --------------------------------------------------------------------------
#charybdis
--------------------------------------------------------------------------- -->
<div
id="charybdis"
class="ircd"
ng-controller="mc"
ng-include="'ircd'"
ircd-catch
>
</div>
<script src="jquery.min.js"></script>
<script src="angular.min.js"></script>
<script src="angular-animate.min.js"></script>
<script src="js/util.js"></script>
<script src="js/debug.js"></script>
<script src="js/ircd.js"></script>
<script src="js/mc.js"></script>
<script src="js/ng.js"></script>
<script src="js/error.js"></script>
<script src="js/watch.js"></script>
<script src="js/task.js"></script>
<script src="js/storage.js"></script>
<script src="js/datetime.js"></script>
<script src="js/random.js"></script>
<script src="js/ui.js"></script>
<script src="js/explore.js"></script>
<script src="js/scroll.js"></script>
<script src="js/menu.js"></script>
<script src="js/io.js"></script>
<script src="js/io.request.js"></script>
<script src="js/m.js"></script>
<script src="js/my.js"></script>
<script src="js/event.js"></script>
<script src="js/user.js"></script>
<script src="js/users.js"></script>
<script src="js/room.js"></script>
<script src="js/room/timeline.js"></script>
<script src="js/room/state.js"></script>
<script src="js/room/power.js"></script>
<script src="js/room/members.js"></script>
<script src="js/room/send.js"></script>
<script src="js/room/typing.js"></script>
<script src="js/room/receipt.js"></script>
<script src="js/room/input.js"></script>
<script src="js/room/input.history.js"></script>
<script src="js/room/attach.js"></script>
<script src="js/room/scroll.js"></script>
<script src="js/room/account.js"></script>
<script src="js/room/notifications.js"></script>
<script src="js/room/dom.js"></script>
<script src="js/room/sync.js"></script>
<script src="js/room/focus.js"></script>
<script src="js/room/events.js"></script>
<script src="js/room/controller.js"></script>
<script src="js/room/misc.js"></script>
<script src="js/rooms.js"></script>
<script src="js/console.js"></script>
<script src="js/settings.js"></script>
<script src="js/filter.js"></script>
<script src="js/sync.js"></script>
<script src="js/auth.js"></script>
<script src="js/main.js"></script>
<script src="construct.js"></script>
</body>
</html>