0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-03 04:18:55 +01:00
construct/modules/static/index.html
2017-08-23 15:28:25 -06:00

2958 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="Charybdis Five Internet Relay Collaboration"
/>
<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="charybdis.css"
/>
<!--
for erry
-->
<title>
Charybdis 5 - Internet Relay Collaboration
</title>
</head>
<body
ng-app="ircd"
ng-class="{ loaded: true }"
>
<!----------------------------------------------------------------------------
Charybdis 5 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_motd"
class="motd pane"
ng-show="mc.show['#charybdis_motd']"
ng-dblclick="mc.show['#charybdis_motd'] = false"
ng-include="'ircd_motd'"
>
</div>
<div
id="charybdis_login"
class="login_ pane"
ng-show="mc.show['#charybdis_login']"
ng-include="'charybdis_login'"
>
</div>
</script>
<!----------------------------------------------------------------------------
Rooms
----------------------------------------------------------------------------->
<script
id="ircd_rooms"
type="text/ng-template"
>
<div
id="charybdis_room"
class="current no-animate"
ng-hide="!mc.rooms.current.list.length"
ng-include="'ircd_rooms_current'"
>
</div>
<div
id="charybdis_rooms_main"
class="main"
ng-if="mc.show['#charybdis_rooms_main']"
ircd-catch='{"delegate": "#charybdis_rooms_list"}'
>
<div
id="charybdis_rooms_head"
class="head"
ng-show="mc.show['#charybdis_menu']"
ng-include="'ircd_rooms_head'"
>
</div>
<div
id="charybdis_rooms_list"
class="list"
ng-if="!empty(mc.rooms.list)"
ng-controller="rooms.list as list"
ang-scroll="list.scroll($event)"
ng-include="'ircd_rooms_list'"
>
</div>
</div>
</script>
<script
id="ircd_rooms_head"
type="text/ng-template"
>
<h1
ng-hide="mc.show['#charybdis_menu']"
>
ROOMS
</h1>
<form
id="charybdis_rooms_menu"
class="menu"
ng-controller="menu as menu"
ng-include="'ircd_rooms_menu'"
>
</form>
<form
id="charybdis_rooms_search"
class="search"
ng-include="'ircd_rooms_search'"
ng-class="
{
selected: mc.rooms.mode == 'SEARCH',
}">
</form>
</script>
<script
id="ircd_rooms_menu"
type="text/ng-template"
>
<button
class="item"
ng-repeat="(name, item) in mc.rooms.menu"
ang-click="menu.toggle(mc.rooms.menu, name, $event)"
style="order: {{item.order !== undefined? item.order : 'initial'}}"
title="{{item.tooltip}}"
ng-hide="item.hide()"
ng-class="
{
selected: menu.selected(mc.rooms.menu, name, item),
error: item.error !== undefined,
disabled: item.disabled === true,
choice: item.choice(),
}">
<i
class="fa icon"
ng-class="item.icon"
aria-hidden="true"
>
</i>
<h3
class="name"
>
{{ name }}
</h3>
</button>
</script>
<script
id="ircd_rooms_search"
type="text/ng-template"
>
<input
name="name"
type="text"
autocomplete="off"
ng-model="mc.rooms.search.value"
ng-model-options="{debounce: 100}"
ng-change="mc.rooms.search.on.change($event);"
ng-keypress="mc.rooms.search.on.keypress($event);"
ng-focus="mc.rooms.search.on.focus($event);"
ng-blur="mc.rooms.search.on.blur($event);"
/>
<label
class="h6"
>
SEARCH ROOMS
<span
ng-hide="empty(mc.rooms.search.value)"
class="feedback"
>
{{ mc.rooms.search.feedback }}
</span>
</label>
</script>
<script
id="ircd_rooms_list"
type="text/ng-template"
>
<div
class="item"
ng-repeat="room in mc.rooms.list"
ng-show="!mc.rooms.info.model || mc.rooms.info.model == room.id"
ng-include="'ircd_rooms_list_item'"
>
</div>
</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.joined[room.id] !== undefined,
invited: mc.rooms.invited[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.joined[room.id] !== undefined,
invited: mc.rooms.invited[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.state['m.room.name'].content.name) &&
empty(room.state['m.room.canonical_alias'].content.alias)"
>
{{ room.id }}
</h3>
<h3
class="right name grow"
ng-if="!empty(room.state['m.room.name'].content.name) &&
empty(room.state['m.room.canonical_alias'].content.alias)"
>
{{ room.state['m.room.name'].content.name }}
</h3>
<h3
class="right alias grow"
ng-if="!empty(room.state['m.room.canonical_alias'].content.alias)"
>
{{ room.state['m.room.canonical_alias'].content.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.state['m.room.name'].content.name }}
</h3>
</div>
<div
class="id"
>
<h4>
{{ room.id }}
</h4>
</div>
<div
class="stats"
>
<div
class="joined"
ng-if="mc.rooms.joined[room.id] !== undefined"
>
<h5
class="label"
>
JOINED
</h5>
<p>
{{mc.date.describe.since(mc.rooms.joined[room.id].membership.me().origin_server_ts)}} ago
({{mc.date.local.pretty(mc.rooms.joined[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>
<script
id="ircd_rooms_current"
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 indicator bar"
ng-show="room.control.show_status_indicator"
ng-include="'ircd_room_control_indicator'"
>
</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'"
>
</div>
<div
class="members"
ng-if="room.control.show_members"
ng-controller="room.membership 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="events"
ng-controller="room.events as events"
ang-scroll="room.scroll.on($event)"
ng-include="'ircd_room_events'"
>
</div>
<form
class="input"
ng-show="room.control.show_main_input && room.control.mode == 'LIVE'"
ng-include="'ircd_room_input'"
>
</form>
</script>
<script
id="ircd_room_members"
type="text/ng-template"
>
<div
class="menu"
ng-include="'ircd_room_members_menu'"
>
</div>
<form
class="search"
ng-include="'ircd_room_members_search'"
>
</form>
<div
class="list"
ang-scroll="members.scroll($event)"
ng-include="'ircd_room_members_list'"
ircd-catch
>
</div>
<div
class="invite member"
ng-show="members.filter == 'invite'"
ng-include="'ircd_room_members_invite'"
>
</div>
</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.control.show_members = members.filter != name;
members.filter = name;
"
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"
>
<input
name="pattern"
type="text"
autocomplete="off"
/>
<label
class="h6"
>
SEARCH MEMBERS
</h6>
</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_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>
<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>
<script
id="charybdis_login"
type="text/ng-template"
>
<form
id="charybdis_login_form"
ircd-catch
>
<h1>
Matrix
</h1>
<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.auth['m.login.password'](); $event.stopPropagation();"
>
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'](); $event.stopPropagation();"
>
REGISTER
</button>
</div>
</form>
</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>
<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.state['m.room.history_visibility'].content.history_visibility == name,
pending: room.pending['m.room.history_visibility'].content.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.state['m.room.join_rules'].content.join_rule == name,
pending: room.pending['m.room.join_rules'].content.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.state['m.room.guest_access'].content.guest_access == name,
pending: room.pending['m.room.guest_access'].content.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.state['m.room.power_levels'].content"
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.state['m.room.name'].content.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.state['m.room.topic'].content.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_indicator"
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.state['m.room.name'].content.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.state['m.room.canonical_alias'].content.alias}}
</h3>
</div>
<div
class="id"
ng-click="room.control.show_detail = !room.control.show_detail"
>
<button
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-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-gears pointer"
aria-hidden="true"
>
</i>
</button>
<div
class="state"
>
<p
class="count"
>
{{ Object.keys(room.state).length }}
</p>
<h5>
ST
</h5>
</div>
<div
class="timeline"
>
<p
class="count"
>
{{ room.timeline.length }}
</p>
<h5>
TL
</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="room.control.show_members = !room.control.show_members"
>
<button
ng-class="
{
selected: room.control.show_members,
}">
<i
class="members icon fa fa-users"
aria-hidden="true"
>
</i>
</button>
<div
ng-repeat="(name, item) in mc.room.membership.indicator"
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_indicator_charybdis_menu'"
>
</div>
</script>
<script
id="ircd_room_control_indicator_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>
<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.state['m.room.member'][event.sender].content.avatar_url"
ng-href="room.state['m.room.member'][event.sender].content.avatar_url"
>
<img
ng-src="room.state['m.room.member'][event.sender].content.avatar_url"
alt="{{ room.state['m.room.member'][event.sender].content.avatar_url }}"
target="_blank"
/>
</a>
<span
class="name"
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"
>
{{ mc.m.sid(event.sender) }}
</span>
</span>
&nbsp;
<span
class="domain"
>{{ mc.m.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__member"
type="text/ng-template"
>
<p
class="join"
ng-switch-when="join"
>
{{ event.content.displayname }} joined the channel.
</p>
<p
class="leave"
ng-switch-when="leave"
ng-if="!event.target || event.target == event.sender"
>
{{ event.content.displayname }} left the channel.
</p>
<p
class="leave"
ng-switch-when="leave"
ng-if="event.target && event.target != event.sender"
>
<b>kicked</b> {{ event.content.displayname }}
</p>
<p
class="invite"
ng-switch-when="invite"
>
<b>invited</b> {{ event.content.displayname }}
</p>
<p
class="default unhandled"
ng-switch-default
>
unhandled m.room.member type '{{ event.content.membership }}'
</p>
</script>
<script
id="ircd_room_event__message"
type="text/ng-template"
>
</script>
<script
id="ircd_room_event__create"
type="text/ng-template"
>
<div
class="changed"
>
<h5>
created
</h5>
<h3>
ROOM
</h3>
</div>
<h1>
{{ id }}
</h1>
</script>
<script
id="ircd_room_event__power_levels"
type="text/ng-template"
>
<div
class="changed"
>
<h5>
changed
</h5>
<h3>
PRIVILEGE LEVELS
</h3>
</div>
<div
class="new levels"
>
<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__canonical_alias"
type="text/ng-template"
>
<div
class="changed"
>
<h5>
changed
</h5>
<h3>
CANONICAL ALIAS
</h3>
</div>
<h2>
{{ event.content.alias }}
</h2>
</script>
<script
id="ircd_room_event__join_rules"
type="text/ng-template"
>
<div
class="changed"
>
<h5>
changed
</h5>
<h3>
JOIN RULES
</h3>
</div>
<div
class="join_rules menu"
>
<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__history_visibility"
type="text/ng-template"
>
<div
class="changed"
>
<h5>
changed
</h5>
<h3>
HISTORY VISIBILITY
</h3>
</div>
<h2>
{{ event.content.history_visibility }}
</h2>
</script>
<script
id="ircd_room_event__guest_access"
type="text/ng-template"
>
<div
class="changed"
>
<h5>
changed
</h5>
<h3>
GUEST ACCESS
</h3>
</div>
<h2>
{{ event.content.guest_access }}
</h2>
</script>
<script
id="ircd_room_event__aliases"
type="text/ng-template"
>
<div
class="changed"
>
<h5>
changed
</h5>
<h3>
ALIASES
</h3>
</div>
<div
class="aliases row nowrap grow center"
>
<h2
class="alias full-center"
ng-repeat="alias in event.content.aliases"
>
{{ alias }}
</h2>
</div>
</script>
<script
id="ircd_room_event_unhandled"
type="text/ng-template"
>
<h4>
UNHANDLED EVENT
</h4>
<p
style="white-space: pre-wrap;"
>
{{ debug.stringify(event, 2) }}
</p>
</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_events"
type="text/ng-template"
>
<div
class="event"
ng-repeat="event in room.timeline"
ng-if="events.can_render(event, $index)"
ng-show="events.can_show(event, $index)"
ng-switch on="event.type"
ng-class="
{
zoom: room.control.content.zoom == event.event_id,
}">
<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-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="member"
ng-switch-when="m.room.member"
>
<div
ng-switch on="event.content.membership"
ng-include="'ircd_room_event__member'"
>
</div>
</div>
<div
class="message"
ng-switch-when="m.room.message"
ng-switch on="event.content.msgtype"
>
<div
class="notice"
ng-switch-when="m.notice"
>{{event.content.body}}</div>
<p
class="text"
ng-switch-when="m.text"
>{{event.content.body}}</p>
<p
class="emote"
ng-switch-when="m.emote"
>{{event.content.body}}</p>
<div
class="image"
ng-switch-when="m.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>
<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>
<p
class="default unhandled"
ng-switch-default
>
unhandled message type '{{ event.content.msgtype }}'
</p>
</div>
<div
class="state create"
ng-switch-when="m.room.create"
>
<div
ng-include="'ircd_room_event__create'"
>
</div>
</div>
<div
class="state power_levels"
ng-switch-when="m.room.power_levels"
>
<div
ng-include="'ircd_room_event__power_levels'"
>
</div>
</div>
<div
class="state canonical_alias"
ng-switch-when="m.room.canonical_alias"
>
<div
ng-include="'ircd_room_event__canonical_alias'"
>
</div>
</div>
<div
class="state join_rules"
ng-switch-when="m.room.join_rules"
>
<div
ng-include="'ircd_room_event__join_rules'"
>
</div>
</div>
<div
class="state history_visibility"
ng-switch-when="m.room.history_visibility"
>
<div
ng-include="'ircd_room_event__history_visibility'"
>
</div>
</div>
<div
class="state guest_access"
ng-switch-when="m.room.guest_access"
>
<div
ng-include="'ircd_room_event__guest_access'"
>
</div>
</div>
<div
class="state aliases"
ng-switch-when="m.room.aliases"
>
<div
ng-include="'ircd_room_event__aliases'"
>
</div>
</div>
<div
class="default unhandled"
ng-switch-default
>
<div
ng-include="'ircd_room_event_unhandled'"
>
</div>
</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_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>
<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.state['m.room.name'].content.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_motd"
type="text/ng-template"
>
<h3>
WELCOME TO CHARYBDIS 5
</h3>
<p>
The free and open-source Internet Relay Collaboration daemon implementing the
<b>Matrix</b> chat federation protocol.
</p>
<h3>
FREE & OPEN SOURCE SOFTWARE COLLABORATION
</h3>
<p>
Charybdis extends the Matrix chat protocol to facilitate collaboration with IRC<sup>3</sup>
("IRC cubed" or "Internet Relay Collaboration") protocol. For capable clients, project files can
be edited by developers and observed by contributors in realtime; live discussions take place
adjacent to the code being developed; a timeline of updates form a commit made to git; webhooks
to Github and <i>continuous integration</i> are conducted by the server.
</p>
<h3>
CHARYBDIS CLUSTER
</h3>
<p>
<i>Cluster</i> facilitates load-balancing and redundancy for groups of
trusted servers. Cluster introduces a technology called <i>Proteus</i>: a <b>single
shared content and event repository among servers</b>, without replicating copies
between them and thus reducing storage cost.
</p>
<h3>
CHARYBDIS PEERING
</h3>
<p>
<i>Peering</i> allows groups of <i>untrusted</i> servers in the federation
that have formed a <i>clique</i> of users, rooms, assets, etc to utilize the same technology
as <i>Charybdis Cluster</i> at a larger scale.
</p>
</script>
<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>
<!-- --------------------------------------------------------------------------
#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="charybdis/util.js"></script>
<script src="charybdis/debug.js"></script>
<script src="charybdis/ircd.js"></script>
<script src="charybdis/mc.js"></script>
<script src="charybdis/ng.js"></script>
<script src="charybdis/error.js"></script>
<script src="charybdis/watch.js"></script>
<script src="charybdis/task.js"></script>
<script src="charybdis/storage.js"></script>
<script src="charybdis/datetime.js"></script>
<script src="charybdis/random.js"></script>
<script src="charybdis/ui.js"></script>
<script src="charybdis/scroll.js"></script>
<script src="charybdis/menu.js"></script>
<script src="charybdis/io.js"></script>
<script src="charybdis/io.request.js"></script>
<script src="charybdis/m.js"></script>
<script src="charybdis/my.js"></script>
<script src="charybdis/event.js"></script>
<script src="charybdis/user.js"></script>
<script src="charybdis/users.js"></script>
<script src="charybdis/room.js"></script>
<script src="charybdis/room/timeline.js"></script>
<script src="charybdis/room/state.js"></script>
<script src="charybdis/room/power.js"></script>
<script src="charybdis/room/members.js"></script>
<script src="charybdis/room/send.js"></script>
<script src="charybdis/room/typing.js"></script>
<script src="charybdis/room/receipt.js"></script>
<script src="charybdis/room/input.js"></script>
<script src="charybdis/room/input.history.js"></script>
<script src="charybdis/room/attach.js"></script>
<script src="charybdis/room/scroll.js"></script>
<script src="charybdis/room/account.js"></script>
<script src="charybdis/room/notifications.js"></script>
<script src="charybdis/room/dom.js"></script>
<script src="charybdis/room/sync.js"></script>
<script src="charybdis/room/focus.js"></script>
<script src="charybdis/room/events.js"></script>
<script src="charybdis/room/controller.js"></script>
<script src="charybdis/room/misc.js"></script>
<script src="charybdis/rooms.js"></script>
<script src="charybdis/rooms/current.js"></script>
<script src="charybdis/rooms/create.js"></script>
<script src="charybdis/rooms/info.js"></script>
<script src="charybdis/rooms/search.js"></script>
<script src="charybdis/rooms/public.js"></script>
<script src="charybdis/rooms/sync.js"></script>
<script src="charybdis/rooms/list.js"></script>
<script src="charybdis/console.js"></script>
<script src="charybdis/settings.js"></script>
<script src="charybdis/filter.js"></script>
<script src="charybdis/sync.js"></script>
<script src="charybdis/auth.js"></script>
<script src="charybdis/main.js"></script>
<script src="charybdis.js"></script>
</body>
</html>