diff options
author | Morris Jobke <hey@morrisjobke.de> | 2016-07-19 13:50:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-19 13:50:32 +0200 |
commit | 47c80ae1cfaf90c90755d5b5a7d7ada0700b3402 (patch) | |
tree | 649ae00570746e3772403b957641f4a8539bf9e6 | |
parent | 13a25535d2c5c6b181ec31a41f76f825414a26f4 (diff) | |
parent | df2dffaf7c5dd7c912e981a7c0bc29f853123551 (diff) | |
download | nextcloud-server-47c80ae1cfaf90c90755d5b5a7d7ada0700b3402.tar.gz nextcloud-server-47c80ae1cfaf90c90755d5b5a7d7ada0700b3402.zip |
Merge pull request #438 from nextcloud/sessions-list-format
format current and sync client sessions in Personal
-rw-r--r-- | settings/Controller/AuthSettingsController.php | 1 | ||||
-rw-r--r-- | settings/js/authtoken_view.js | 130 |
2 files changed, 97 insertions, 34 deletions
diff --git a/settings/Controller/AuthSettingsController.php b/settings/Controller/AuthSettingsController.php index e7fc2d916bc..47ab1fc03fd 100644 --- a/settings/Controller/AuthSettingsController.php +++ b/settings/Controller/AuthSettingsController.php @@ -98,6 +98,7 @@ class AuthSettingsController extends Controller { $data = $token->jsonSerialize(); if ($sessionToken->getId() === $token->getId()) { $data['canDelete'] = false; + $data['current'] = true; } else { $data['canDelete'] = true; } diff --git a/settings/js/authtoken_view.js b/settings/js/authtoken_view.js index 472b841c230..2ebedb4131c 100644 --- a/settings/js/authtoken_view.js +++ b/settings/js/authtoken_view.js @@ -20,14 +20,14 @@ * */ -(function(OC, _, $, Handlebars, moment) { +(function (OC, _, $, Handlebars, moment) { 'use strict'; OC.Settings = OC.Settings || {}; var TEMPLATE_TOKEN = '<tr data-id="{{id}}">' - + '<td class="has-tooltip" title="{{name}}"><span class="token-name">{{name}}</span></td>' + + '<td class="has-tooltip" title="{{title}}"><span class="token-name">{{name}}</span></td>' + '<td><span class="last-activity has-tooltip" title="{{lastActivityTime}}">{{lastActivity}}</span></td>' + '{{#if canDelete}}' + '<td><a class="icon-delete has-tooltip" title="' + t('core', 'Disconnect') + '"></a></td>' @@ -50,7 +50,7 @@ _template: undefined, - template: function(data) { + template: function (data) { if (_.isUndefined(this._template)) { this._template = Handlebars.compile(TEMPLATE_TOKEN); } @@ -58,18 +58,18 @@ return this._template(data); }, - initialize: function(options) { + initialize: function (options) { this.type = options.type; this.collection = options.collection; this.on(this.collection, 'change', this.render); }, - render: function() { + render: function () { var _this = this; var list = this.$('.token-list'); - var tokens = this.collection.filter(function(token) { + var tokens = this.collection.filter(function (token) { return parseInt(token.get('type'), 10) === _this.type; }); list.html(''); @@ -77,24 +77,86 @@ // Show header only if there are tokens to show this._toggleHeader(tokens.length > 0); - tokens.forEach(function(token) { - var viewData = token.toJSON(); - var ts = viewData.lastActivity * 1000; - viewData.lastActivity = OC.Util.relativeModifiedDate(ts); - viewData.lastActivityTime = OC.Util.formatDate(ts, 'LLL'); + tokens.forEach(function (token) { + var viewData = this._formatViewData(token.toJSON()); var html = _this.template(viewData); var $html = $(html); $html.find('.has-tooltip').tooltip({container: 'body'}); list.append($html); - }); + }.bind(this)); }, - toggleLoading: function(state) { + toggleLoading: function (state) { this.$('.token-list').toggleClass('icon-loading', state); }, - _toggleHeader: function(show) { + _toggleHeader: function (show) { this.$('.hidden-when-empty').toggleClass('hidden', !show); + }, + + _formatViewData: function (viewData) { + var ts = viewData.lastActivity * 1000; + viewData.lastActivity = OC.Util.relativeModifiedDate(ts); + viewData.lastActivityTime = OC.Util.formatDate(ts, 'LLL'); + + // preserve title for cases where we format it further + viewData.title = viewData.name; + + // pretty format sync client user agent + var matches = viewData.name.match(/Mozilla\/5\.0 \((\w+)\) (?:mirall|csyncoC)\/(\d+\.\d+\.\d+)/); + + var userAgentMap = { + ie: /(?:MSIE|Trident) (\d+)/, + // Microsoft Edge User Agent from https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx + edge: /^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/[0-9.]+ (?:Mobile Safari|Safari)\/[0-9.]+ Edge\/[0-9.]+$/, + // Firefox User Agent from https://developer.mozilla.org/en-US/docs/Web/HTTP/Gecko_user_agent_string_reference + firefox: /^Mozilla\/5\.0 \([^)]*(Windows|OS X|Linux)[^)]+\) Gecko\/[0-9.]+ Firefox\/(\d+)(?:\.\d)?$/, + // Chrome User Agent from https://developer.chrome.com/multidevice/user-agent + chrome: /^Mozilla\/5\.0 \([^)]*(Windows|OS X|Linux)[^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Chrome\/(\d+)[0-9.]+ (?:Mobile Safari|Safari)\/[0-9.]+$/, + // Safari User Agent from http://www.useragentstring.com/pages/Safari/ + safari: /^Mozilla\/5\.0 \([^)]+\) AppleWebKit\/[0-9.]+ \(KHTML, like Gecko\) Version\/([0-9]+)[0-9.]+ Safari\/[0-9.A-Z]+$/, + // Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent + androidChrome: /Android.*(?:; (.*) Build\/).*Chrome\/(\d+)[0-9.]+/, + iphone: / *CPU +iPhone +OS +(\d+)_\d+ +like +Mac +OS +X */, + iosClient: /^Mozilla\/5\.0 \(iOS\) ownCloud\-iOS.*$/, + androidClient:/^Mozilla\/5\.0 \(Android\) ownCloud\-android.*$/, + // DAVdroid/1.2 (2016/07/03; dav4android; okhttp3) Android/6.0.1 + davDroid: /DAVdroid\/([0-9.]+)/ + }; + var nameMap = { + ie: t('setting', 'Internet Explorer'), + edge: t('setting', 'Edge'), + firefox: t('setting', 'Firefox'), + chrome: t('setting', 'Google Chrome'), + safari: t('setting', 'Safari'), + androidChrome: t('setting', 'Google Chrome for Android'), + iphone: t('setting', 'iPhone'), + iosClient: t('setting', 'iOS Client'), + androidClient: t('setting', 'Android Client'), + davDroid: 'DAVdroid' + }; + + if (matches) { + viewData.name = t('settings', 'Sync client - {os}', { + os: matches[1], + version: matches[2] + }); + } + for (var client in userAgentMap) { + if (matches = viewData.title.match(userAgentMap[client])) { + if (matches[2] && matches[1]) { // version number and os + viewData.name = nameMap[client] + ' ' + matches[2] + ' - ' + matches[1]; + }else if (matches[1]) { // only version number + viewData.name = nameMap[client] + ' ' + matches[1]; + } else { + viewData.name = nameMap[client]; + } + } + } + if (viewData.current) { + viewData.name = t('settings', 'This session'); + } + return viewData; } }); @@ -119,12 +181,12 @@ _addingToken: false, - initialize: function(options) { + initialize: function (options) { this.collection = options.collection; var tokenTypes = [0, 1]; var _this = this; - _.each(tokenTypes, function(type) { + _.each(tokenTypes, function (type) { var el = type === 0 ? '#sessions' : '#apppasswords'; _this._views.push(new SubView({ el: el, @@ -150,31 +212,31 @@ this._hideAppPasswordBtn.click(_.bind(this._hideToken, this)); }, - render: function() { - _.each(this._views, function(view) { + render: function () { + _.each(this._views, function (view) { view.render(); view.toggleLoading(false); }); }, - reload: function() { + reload: function () { var _this = this; - _.each(this._views, function(view) { + _.each(this._views, function (view) { view.toggleLoading(true); }); var loadingTokens = this.collection.fetch(); - $.when(loadingTokens).done(function() { + $.when(loadingTokens).done(function () { _this.render(); }); - $.when(loadingTokens).fail(function() { + $.when(loadingTokens).fail(function () { OC.Notification.showTemporary(t('core', 'Error while loading browser sessions and device tokens')); }); }, - _addAppPassword: function() { + _addAppPassword: function () { var _this = this; this._toggleAddingToken(true); @@ -186,7 +248,7 @@ } }); - $.when(creatingToken).done(function(resp) { + $.when(creatingToken).done(function (resp) { _this.collection.add(resp.deviceToken); _this.render(); _this._newAppLoginName.val(resp.loginName); @@ -195,32 +257,32 @@ _this._newAppPassword.select(); _this._tokenName.val(''); }); - $.when(creatingToken).fail(function() { + $.when(creatingToken).fail(function () { OC.Notification.showTemporary(t('core', 'Error while creating device token')); }); - $.when(creatingToken).always(function() { + $.when(creatingToken).always(function () { _this._toggleAddingToken(false); }); }, - _onNewTokenLoginNameFocus: function() { + _onNewTokenLoginNameFocus: function () { this._newAppLoginName.select(); }, - _onNewTokenFocus: function() { + _onNewTokenFocus: function () { this._newAppPassword.select(); }, - _hideToken: function() { + _hideToken: function () { this._toggleFormResult(true); }, - _toggleAddingToken: function(state) { + _toggleAddingToken: function (state) { this._addingToken = state; this._addAppPasswordBtn.toggleClass('icon-loading-small', state); }, - _onDeleteToken: function(event) { + _onDeleteToken: function (event) { var $target = $(event.target); var $row = $target.closest('tr'); var id = $row.data('id'); @@ -236,15 +298,15 @@ $row.find('.icon-delete').tooltip('hide'); var _this = this; - $.when(destroyingToken).fail(function() { + $.when(destroyingToken).fail(function () { OC.Notification.showTemporary(t('core', 'Error while deleting the token')); }); - $.when(destroyingToken).always(function() { + $.when(destroyingToken).always(function () { _this.render(); }); }, - _toggleFormResult: function(showForm) { + _toggleFormResult: function (showForm) { this._form.toggleClass('hidden', !showForm); this._result.toggleClass('hidden', showForm); } |