151:0178573216e3
Anton Shestakov <av6@dwimlabs.net>, Thu, 14 Apr 2016 02:05:24 +0800
index: remove offline contacts only when they change to being offline Since new contacts are currently added while they still have the default presence of 'unavailable', add event sees them as offline and throws them away immediately, before their presence could change to something else.

next change 161:f4d47c72e93b
previous change 147:acd87ac0182d

index.html

Permissions: -rw-r--r--

Other formats: Feeds:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tram IM</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.26.2/css/uikit.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.26.2/css/components/progress.min.css">
<link rel="stylesheet" href="/css/tram-im.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rivets/0.8.1/rivets.bundled.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/2.26.2/js/uikit.min.js"></script>
<script src="/vendor/strophejs/strophe.min.js"></script>
<script src="/vendor/strophejs-plugins/disco/strophe.disco.js"></script>
<script src="/vendor/strophejs-plugins/ping/strophe.ping.js"></script>
<script src="/vendor/strophejs-plugins/register/strophe.register.js"></script>
<script src="/vendor/strophejs-plugins/roster/strophe.roster.js"></script>
<script src="/vendor/strophejs-plugins/vcard/strophe.vcard.js"></script>
<script src="/vendor/webrtc-adapter-1.0.4.js"></script>
</head>
<body>
<div class="uk-progress uk-progress-mini page-progress" data-app="progress" rv-hide="model:progress | eq undefined">
<div class="uk-progress-bar" rv-style="model:progress | fn view.getStyle"></div>
</div>
<div class="smart-container" data-step="noscript">
<div class="uk-alert">
<p class="uk-text-center">This page needs JavaScript to work.</p>
<hr>
<small>It uses resources from cdnjs.cloudflare.com.</small>
</div>
</div>
<div class="smart-container uk-hidden" data-step="login">
<div class="uk-form uk-form-horizontal" data-form="connect">
<div class="uk-form-row">
<label for="username" class="uk-form-label">Username</label>
<div class="uk-form-controls">
<input id="username" type="text" class="uk-width-1-1" required autofocus
rv-value="data:username" rv-class-uk-form-danger="data:username-errors">
<div class="uk-text-danger" rv-each-error="data:username-errors">{ error }</div>
</div>
</div>
<div class="uk-form-row">
<label for="password" class="uk-form-label">Password</label>
<div class="uk-form-controls">
<input id="password" type="password" class="uk-width-1-1" required
rv-value="data:password" rv-class-uk-form-danger="data:password-errors">
<div class="uk-text-danger" rv-each-error="data:password-errors">{ error }</div>
</div>
</div>
<div class="uk-form-row">
<div class="uk-form-controls">
<div class="uk-alert uk-alert-danger" rv-each-error="data:auth-errors">{ error }</div>
<button type="button" class="uk-button uk-button-primary" rv-on-click="connect">
<i class="uk-icon-sign-in"></i>&nbsp;Log in
</button>
<a class="uk-float-right uk-button uk-button-link" href="/register.html">Register</a>
</div>
</div>
</div>
</div>
<script>
$('[data-step="noscript"]').addClass('uk-hidden');
</script>
<div class="has-sidebar uk-hidden" data-step="main">
<div class="sidebar" data-app="sidebar" rv-class-mini="model:sidebar/minified">
<ul class="uk-nav uk-nav-side uk-nav-offcanvas uk-text-nowrap">
<li class="uk-text-center">
<a rv-on-click="view.minify">
<i class="uk-icon-chevron-right" rv-if="model:sidebar/minified"></i>
<i class="uk-icon-chevron-left" rv-unless="model:sidebar/minified"></i>
</a>
</li>
<li class="uk-nav-divider"></li>
<li rv-class-uk-active="model:show | eq 'chat'">
<a data-show="chat" rv-on-click="view.show">
<div class="status-pip" rv-style="'chat' | fn view.getPipColor"></div>
<span class="label">Ready to chat</span>
</a>
</li>
<li rv-class-uk-active="model:show | eq 'online'">
<a data-show="online" rv-on-click="view.show">
<div class="status-pip" rv-style="'online' | fn view.getPipColor"></div>
<span class="label">Online</span>
</a>
</li>
<li rv-class-uk-active="model:show | eq 'away'">
<a data-show="away" rv-on-click="view.show">
<div class="status-pip" rv-style="'away' | fn view.getPipColor"></div>
<span class="label">Away</span>
</a>
</li>
<li rv-class-uk-active="model:show | eq 'xa'">
<a data-show="xa" rv-on-click="view.show">
<div class="status-pip" rv-style="'xa' | fn view.getPipColor"></div>
<span class="label">Gone</span>
</a>
</li>
<li class="uk-nav-divider"></li>
<li>
<a data-uk-modal="{target:'#profile-modal'}">
<i class="uk-icon-info-circle"></i>
<span class="label">Profile</span>
</a>
</li>
<li class="uk-nav-divider"></li>
<li>
<a rv-on-click="view.disconnect">
<i class="uk-icon-sign-out"></i>
<span class="label">Log out</span>
</a>
</li>
</ul>
<div class="uk-panel">
<p rv-if="model:server/name">
Server: { model:server/name } { model:server/version } on { model:server/os }
</p>
</div>
</div>
<div data-app="calls"></div>
<div class="uk-grid main-grid">
<div class="uk-width-xlarge-1-4 uk-width-large-1-3 uk-width-medium-1-2 contact-list-block">
<ul class="uk-list contact-list" data-app="contacts"></ul>
<div class="uk-form input-group">
<input id="new-contact" type="text" value="" placeholder="add a contact" required>
<span class="input-group-button">
<button type="button" class="uk-button uk-button-success" data-add-button>
<i class="uk-icon-user-plus"></i>
</button>
</span>
</div>
</div>
<div class="uk-width-xlarge-3-4 uk-width-large-2-3 uk-width-medium-1-2">
<div data-app="logs"></div>
<div class="uk-form input-group uk-hidden" data-form="send">
<input id="msg" type="text" value="" placeholder="send a message" required>
<span class="input-group-button">
<button class="uk-button uk-button-primary" data-send-button>
<i class="uk-icon-paper-plane"></i>
</button>
</span>
</div>
</div>
</div>
</div>
<div id="profile-modal" class="uk-modal">
<div class="uk-modal-dialog">
<button type="button" class="uk-modal-close uk-close"></button>
<div class="uk-modal-header"><h2>Profile</h2></div>
<dl data-app="profile">
<dt>Full Name</dt>
<dd>{ contact:fullname }</dd>
<dt>Nickname</dt>
<dd>{ contact:nickname }</dd>
<dt>Avatar</dt>
<dd><img rv-if="contact:avatar/url" rv-src="contact:avatar/url"></dd>
</dl>
<div class="uk-text-right">
<button class="uk-button uk-button-danger uk-modal-close" data-unregister-button>Remove account</button>
</div>
</div>
</div>
<script type="text/template" id="video-block-template">
<video class="remote" rv-src="model:remote/stream/url" autoplay></video>
<video class="local" rv-src="model:local/stream/url" autoplay muted></video>
<div class="buttons uk-text-center">
<button type="button" class="uk-button uk-button-success autofade" data-mute-cam
rv-if="model:local/stream" rv-hide="model:local/video/muted">
<i class="uk-icon-eye"></i>
</button>
<button type="button" class="uk-button uk-button-danger" data-unmute-cam
rv-if="model:local/stream" rv-show="model:local/video/muted">
<i class="uk-icon-eye-slash"></i>
</button>
<button type="button" class="uk-button uk-button-success autofade" data-mute-mic
rv-if="model:local/stream" rv-hide="model:local/audio/muted">
<i class="uk-icon-microphone"></i>
</button>
<button type="button" class="uk-button uk-button-danger" data-unmute-mic
rv-if="model:local/stream" rv-show="model:local/audio/muted">
<i class="uk-icon-microphone-slash"></i>
</button>
<button type="button" class="uk-button uk-button-success autofade" data-mute-audio
rv-if="model:remote/stream" rv-hide="model:remote/audio/muted">
<i class="uk-icon-volume-up"></i>
</button>
<button type="button" class="uk-button uk-button-danger" data-unmute-audio
rv-if="model:remote/stream" rv-show="model:remote/audio/muted">
<i class="uk-icon-volume-off"></i>
</button>
</div>
</script>
<script type="text/template" id="avatar-template">
<img class="avatar" rv-if="model:avatar/url" rv-src="model:avatar/url">
<div class="avatar" rv-unless="model:avatar/url" rv-style="model:bjid | dumb-hash | fn view.getColors">
{ model:d/handle | first-letter }
</div>
</script>
<script type="text/template" id="message-template">
<div class="splitter" rv-if="model:d/split"></div>
<div class="column avatar-column" rv-class-uk-invisible="model:d/fold"></div>
<div class="column text-column">
<div rv-hide="model:d/fold">
<strong>{ view.getHandle < model:contact:d/handle model:from }</strong>
</div>
<div rv-class="model:cls">
<time class="stamp uk-text-muted uk-float-right"
rv-datetime="model:d/mstamp | iso-date"
rv-title="model:d/mstamp | format-date 'HH:mm:ss'">
{ model:d/mstamp | from-now }
</time>
<div rv-unless="model:html">{ model:text }</div>
<div class="xhtml-body" rv-if="model:html" rv-html="model:html"></div>
</div>
</div>
</script>
<script type="text/template" id="contact-template">
<div class="column avatar-column">
<div class="status-pip" rv-title="model:show" rv-style="model:show | fn view.getPipColor"></div>
</div>
<div class="column uk-width-1-1">
<div class="uk-text-bold">{ model:d/handle }</div>
<div class="uk-text-nowrap">
<span>{ model:status }</span>
<span rv-hide="model:type | eq 'self'">{ model:chatstate | only 'composing' }</span>
</div>
</div>
<div class="column uk-text-nowrap">
<i class="uk-icon-phone calling-icon" data-wait rv-if="model:d/actions | has 'wait'"></i>
<button type="button" class="uk-button" data-call="av" rv-if="model:d/actions | has 'call'">
<i class="uk-icon-video-camera"></i>
</button>
<button type="button" class="uk-button" data-call="a" rv-if="model:d/actions | has 'call'">
<i class="uk-icon-phone"></i>
</button>
<button type="button" class="uk-button uk-button-success" data-accept="av" rv-if="model:d/actions | has 'accept'">
<i class="uk-icon-video-camera"></i>
</button>
<button type="button" class="uk-button uk-button-success" data-accept="a" rv-if="model:d/actions | has 'accept'">
<i class="uk-icon-phone"></i>
</button>
<button type="button" class="uk-button uk-button-danger" data-decline rv-if="model:d/actions | has 'decline'">
<i class="uk-icon-times"></i>
</button>
<button type="button" class="uk-button uk-button-danger" data-hang-up rv-if="model:d/actions | has 'hang-up'">
<i class="uk-icon-phone"></i> Hang up
</button>
<button type="button" class="uk-button" data-chat>
<i class="uk-icon-comments-o"></i>
</button>
<div class="uk-button-dropdown" data-uk-dropdown="{mode:'click',pos:'bottom-right'}" rv-if="model:d/actions | has 'remove'">
<button class="uk-button"><i class="uk-icon-caret-down"></i></button>
<div class="uk-dropdown uk-dropdown-small">
<ul class="uk-nav uk-nav-dropdown">
<li><a data-remove rv-if="model:d/actions | has 'remove'">Remove</a></li>
</ul>
</div>
</div>
</div>
<div class="uk-text-center">
<button type="button" class="uk-button uk-button-success" data-authorize rv-if="model:d/actions | has 'authorize'">
<i class="uk-icon-plus"></i> Authorize
</button>
<button type="button" class="uk-button uk-button-danger" data-unauthorize rv-if="model:d/actions | has 'unauthorize'">
<i class="uk-icon-times"></i> Decline
</button>
</div>
</script>
<script src='/js/tram.js'></script>
<script src='/js/rivets.js'></script>
<script src='/js/xmpp.js'></script>
<script src='/js/webrtc.js'></script>
<script src='/js/contacts.js'></script>
<script src='/js/messages.js'></script>
<script src='/js/calls.js'></script>
<script src='/js/favicon.js'></script>
<script src='/js/sidebar.js'></script>
<script src='/js/progress.js'></script>
<script src='/config.js'></script>
<script src='/js/index.js'></script>
<script>
$('[data-step="login"]').removeClass('uk-hidden');
</script>
</body>
</html>