From 3acc01535cc1ec66680905a12e3a7e78ad21125d Mon Sep 17 00:00:00 2001 From: blavenie <benoit.lavenier@e-is.pro> Date: Fri, 7 Aug 2020 21:01:29 +0200 Subject: [PATCH] [enh] Manage #/app/home?uri= to parse g1:// link --- www/index.html | 1 + www/js/controllers.js | 1 + www/js/controllers/app-controllers.js | 169 ------------------ www/js/controllers/home-controllers.js | 226 +++++++++++++++++++++++++ www/js/platform.js | 12 ++ www/js/services/http-services.js | 8 +- 6 files changed, 245 insertions(+), 172 deletions(-) create mode 100644 www/js/controllers/home-controllers.js diff --git a/www/index.html b/www/index.html index 7e6cf4490..4e67c36fb 100644 --- a/www/index.html +++ b/www/index.html @@ -162,6 +162,7 @@ <!-- controllers --> <script src="dist/dist_js/app/controllers/app-controllers.js"></script> + <script src="dist/dist_js/app/controllers/home-controllers.js"></script> <script src="dist/dist_js/app/controllers/join-controllers.js"></script> <script src="dist/dist_js/app/controllers/login-controllers.js"></script> <script src="dist/dist_js/app/controllers/help-controllers.js"></script> diff --git a/www/js/controllers.js b/www/js/controllers.js index 5ed49c515..b36e1e613 100644 --- a/www/js/controllers.js +++ b/www/js/controllers.js @@ -1,6 +1,7 @@ angular.module('cesium.controllers', [ 'cesium.app.controllers', + 'cesium.home.controllers', 'cesium.join.controllers', 'cesium.login.controllers', 'cesium.help.controllers', diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js index 7a12d4e33..8fa7643ef 100644 --- a/www/js/controllers/app-controllers.js +++ b/www/js/controllers/app-controllers.js @@ -15,16 +15,6 @@ angular.module('cesium.app.controllers', ['cesium.platform', 'cesium.services']) } }) - .state('app.home', { - url: "/home?error", - views: { - 'menuContent': { - templateUrl: "templates/home/home.html", - controller: 'HomeCtrl' - } - } - }) - .state('app.lock', { cache: false, url: "/lock", @@ -37,15 +27,10 @@ angular.module('cesium.app.controllers', ['cesium.platform', 'cesium.services']) }) ; - // if none of the above states are matched, use this as the fallback - $urlRouterProvider.otherwise('/app/home'); - }) .controller('AppCtrl', AppController) - .controller('HomeCtrl', HomeController) - .controller('PluginExtensionPointCtrl', PluginExtensionPointController) ; @@ -525,157 +510,3 @@ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $ $scope.askFullscreen(); // endRemoveIf(device) } - - -function HomeController($scope, $state, $timeout, $ionicHistory, $translate, $http, UIUtils, - csConfig, csCache, csPlatform, csCurrency, csSettings) { - 'ngInject'; - - $scope.loading = true; - $scope.locales = angular.copy(csSettings.locales); - $scope.smallscreen = UIUtils.screen.isSmall(); - $scope.showInstallHelp = false; - - $scope.enter = function(e, state) { - if (ionic.Platform.isIOS()) { - if(window.StatusBar) { - // needed to fix Xcode 9 / iOS 11 issue with blank space at bottom of webview - // https://github.com/meteor/meteor/issues/9041 - StatusBar.overlaysWebView(false); - StatusBar.overlaysWebView(true); - } - } - - if (state && state.stateParams && state.stateParams.error) { // Error query parameter - $scope.error = state.stateParams.error; - $scope.node = csCurrency.data.node; - $scope.loading = false; - $ionicHistory.nextViewOptions({ - disableAnimate: true, - disableBack: true, - historyRoot: true - }); - $state.go('app.home', {error: undefined}, { - reload: false, - inherit: true, - notify: false}); - } - else { - // Wait platform to be ready - csPlatform.ready() - .then(function() { - $scope.loading = false; - $scope.loadFeeds(); - }) - .catch(function(err) { - $scope.node = csCurrency.data.node; - $scope.loading = false; - $scope.error = err; - }); - } - }; - $scope.$on('$ionicView.enter', $scope.enter); - - $scope.reload = function() { - $scope.loading = true; - delete $scope.error; - - $timeout($scope.enter, 200); - }; - - $scope.loadFeeds = function() { - var feedUrl = csSettings.getFeedUrl(); - if (!feedUrl || typeof feedUrl !== 'string') return; // Skip - - var maxContentLength = (csConfig.feed && csConfig.feed.maxContentLength) || 650; - - var now = Date.now(); - console.debug("[home] Loading feeds from {0}...".format(feedUrl)); - - $http.get(feedUrl, {responseType: 'json', cache: csCache.get(null, csCache.constants.LONG)}) - .success(function(feed) { - console.debug('[home] Feeds loaded in {0}ms'.format(Date.now()-now)); - if (!feed || !feed.items ||Â !feed.items.length) return; // skip if empty - - feed.items = feed.items.reduce(function(res, item) { - if (!item ||Â (!item.title && !item.content_text && !item.content_html)) return res; // Skip - - // Convert UTC time - if (item.date_published) { - item.time = moment.utc(item.date_published).unix(); - } - // Convert content to HTML - if (item.content_html) { - item.content = item.content_html; - } - else { - item.content = (item.content_text||'').replace(/\n/g, '<br/>'); - } - - // Trunc content, if need - if (maxContentLength !== -1 && item.content && item.content.length > maxContentLength) { - var endIndex = Math.max(item.content.lastIndexOf(" ", maxContentLength), item.content.lastIndexOf("<", maxContentLength)); - item.content = item.content.substr(0, endIndex) + ' (...)'; - item.truncated = true; - } - - // If author is missing, copy the main author - item.author = item.author || feed.author; - - return res.concat(item); - }, []); - - $scope.feed = feed; - }) - .error(function(data, status) { - console.error('[home] Failed to load feeds.'); - $scope.feed = null; - }); - }; - - /** - * Catch click for quick fix - * @param event - */ - $scope.doQuickFix = function(action) { - if (action === 'settings') { - $ionicHistory.nextViewOptions({ - historyRoot: true - }); - $state.go('app.settings'); - } - }; - - $scope.changeLanguage = function(langKey) { - $translate.use(langKey); - $scope.hideLocalesPopover(); - csSettings.data.locale = _.findWhere($scope.locales, {id: langKey}); - csSettings.store(); - $scope.loadFeeds(); - }; - - /* -- show/hide locales popup -- */ - - $scope.showLocalesPopover = function(event) { - UIUtils.popover.show(event, { - templateUrl: 'templates/common/popover_locales.html', - scope: $scope, - autoremove: true, - afterShow: function(popover) { - $scope.localesPopover = popover; - } - }); - }; - - $scope.hideLocalesPopover = function() { - if ($scope.localesPopover) { - $scope.localesPopover.hide(); - $scope.localesPopover = null; - } - }; - - // For DEV ONLY - /*$timeout(function() { - $scope.loginAndGo(); - }, 500);*/ -} diff --git a/www/js/controllers/home-controllers.js b/www/js/controllers/home-controllers.js new file mode 100644 index 000000000..9898e8766 --- /dev/null +++ b/www/js/controllers/home-controllers.js @@ -0,0 +1,226 @@ +angular.module('cesium.home.controllers', ['cesium.platform', 'cesium.services']) + + .config(function($stateProvider, $urlRouterProvider) { + 'ngInject'; + + $stateProvider + + + .state('app.home', { + url: "/home?error&uri", + views: { + 'menuContent': { + templateUrl: "templates/home/home.html", + controller: 'HomeCtrl' + } + } + }) + + ; + + // if none of the above states are matched, use this as the fallback + $urlRouterProvider.otherwise('/app/home'); + + }) + + .controller('HomeCtrl', HomeController) +; + +function HomeController($scope, $state, $timeout, $ionicHistory, $translate, $http, UIUtils, + csConfig, csCache, csPlatform, csCurrency, csSettings, csHttp) { + 'ngInject'; + + $scope.loading = true; + $scope.locales = angular.copy(csSettings.locales); + $scope.smallscreen = UIUtils.screen.isSmall(); + $scope.showInstallHelp = false; + + $scope.enter = function(e, state) { + if (ionic.Platform.isIOS()) { + if(window.StatusBar) { + // needed to fix Xcode 9 / iOS 11 issue with blank space at bottom of webview + // https://github.com/meteor/meteor/issues/9041 + StatusBar.overlaysWebView(false); + StatusBar.overlaysWebView(true); + } + } + + if (state && state.stateParams && state.stateParams.uri) { + return $scope.redirectFromUri(state.stateParams.uri); + } + else if (state && state.stateParams && state.stateParams.error) { // Error query parameter + $scope.error = state.stateParams.error; + $scope.node = csCurrency.data.node; + $scope.loading = false; + $ionicHistory.nextViewOptions({ + disableAnimate: true, + disableBack: true, + historyRoot: true + }); + $state.go('app.home', {error: undefined}, { + reload: false, + inherit: true, + notify: false}); + } + else { + // Wait platform to be ready + csPlatform.ready() + .then(function() { + $scope.loading = false; + $scope.loadFeeds(); + }) + .catch(function(err) { + $scope.node = csCurrency.data.node; + $scope.loading = false; + $scope.error = err; + }); + } + }; + $scope.$on('$ionicView.enter', $scope.enter); + + $scope.reload = function() { + $scope.loading = true; + delete $scope.error; + + $timeout($scope.enter, 200); + }; + + $scope.loadFeeds = function() { + var feedUrl = csSettings.getFeedUrl(); + if (!feedUrl || typeof feedUrl !== 'string') return; // Skip + + var maxContentLength = (csConfig.feed && csConfig.feed.maxContentLength) || 650; + + var now = Date.now(); + console.debug("[home] Loading feeds from {0}...".format(feedUrl)); + + $http.get(feedUrl, {responseType: 'json', cache: csCache.get(null, csCache.constants.LONG)}) + .success(function(feed) { + console.debug('[home] Feeds loaded in {0}ms'.format(Date.now()-now)); + if (!feed || !feed.items ||Â !feed.items.length) return; // skip if empty + + feed.items = feed.items.reduce(function(res, item) { + if (!item ||Â (!item.title && !item.content_text && !item.content_html)) return res; // Skip + + // Convert UTC time + if (item.date_published) { + item.time = moment.utc(item.date_published).unix(); + } + // Convert content to HTML + if (item.content_html) { + item.content = item.content_html; + } + else { + item.content = (item.content_text||'').replace(/\n/g, '<br/>'); + } + + // Trunc content, if need + if (maxContentLength !== -1 && item.content && item.content.length > maxContentLength) { + var endIndex = Math.max(item.content.lastIndexOf(" ", maxContentLength), item.content.lastIndexOf("<", maxContentLength)); + item.content = item.content.substr(0, endIndex) + ' (...)'; + item.truncated = true; + } + + // If author is missing, copy the main author + item.author = item.author || feed.author; + + return res.concat(item); + }, []); + + $scope.feed = feed; + }) + .error(function(data, status) { + console.error('[home] Failed to load feeds.'); + $scope.feed = null; + }); + }; + + /** + * Catch click for quick fix + * @param action + */ + $scope.doQuickFix = function(action) { + if (action === 'settings') { + $ionicHistory.nextViewOptions({ + historyRoot: true + }); + $state.go('app.settings'); + } + }; + + $scope.changeLanguage = function(langKey) { + $translate.use(langKey); + $scope.hideLocalesPopover(); + csSettings.data.locale = _.findWhere($scope.locales, {id: langKey}); + csSettings.store(); + $scope.loadFeeds(); + }; + + /* -- show/hide locales popup -- */ + + $scope.showLocalesPopover = function(event) { + UIUtils.popover.show(event, { + templateUrl: 'templates/common/popover_locales.html', + scope: $scope, + autoremove: true, + afterShow: function(popover) { + $scope.localesPopover = popover; + } + }); + }; + + $scope.hideLocalesPopover = function() { + if ($scope.localesPopover) { + $scope.localesPopover.hide(); + $scope.localesPopover = null; + } + }; + + /** + * Parse an URI (see g1lien) + * @param uri + * @returns {*} + */ + $scope.redirectFromUri = function(uri) { + console.debug("[home] Detecting external uri: ", uri); + var parts = csHttp.uri.parse(uri); + + if (parts.protocol === 'g1:') { + console.debug("[home] Applying g1 uri...", parts); + + // Transfer + if (parts.hostname && parts.search.indexOf('amount=') !== -1) { + return $state.go('app.new_transfer_pubkey', { + pubkey: parts.hostname + }); + } + + // Pubkey + else if (parts.hostname && BMA.regexp.PUBKEY.test(parts.hostname)) { + var pubkey = parts.hostname; + return $state.go('app.wot_identity', { + pubkey: pubkey + }); + } + + // Search by uid + else if (parts.hostname && BMA.regexp.USER_ID.test(parts.hostname)) { + var uid = parts.hostname; + return $state.go('app.wot_lookup.tab_search', { + q: uid + }); + } + } + else { + console.error("[home] Unknown protocol, in URI: " + uri); + } + + // Redirect to home + return $state.go('app.home'); + } + + // For DEV ONLY + /*$timeout(function() { + $scope.loginAndGo(); + }, 500);*/ +} diff --git a/www/js/platform.js b/www/js/platform.js index e243bc417..e08150988 100644 --- a/www/js/platform.js +++ b/www/js/platform.js @@ -229,6 +229,16 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services'] return $q.when(); } + function registerProtocol() { + console.debug("[platform] Register protocol g1://") + try { + navigator.registerProtocolHandler("web+june", "#/app/home?uri=%s", "Cesium"); + } + catch(err) { + console.error(err) + } + } + function addListeners() { listeners = [ // Listen if node changed @@ -261,6 +271,8 @@ angular.module('cesium.platform', ['ngIdle', 'cesium.config', 'cesium.services'] // Avoid change state disableChangeState(); + registerProtocol(); + // We use 'ionicReady()' instead of '$ionicPlatform.ready()', because this one is callable many times startPromise = ionicReady() diff --git a/www/js/services/http-services.js b/www/js/services/http-services.js index 8ce34f453..ad5f86cf5 100644 --- a/www/js/services/http-services.js +++ b/www/js/services/http-services.js @@ -318,9 +318,11 @@ angular.module('cesium.http.services', ['cesium.cache.services']) // See doc : https://gist.github.com/jlong/2428561 function parseUri(uri) { var protocol; - if (uri.startsWith('duniter://')) { - protocol = 'duniter'; - uri = uri.replace('duniter://', 'http://'); + + // G1 URI (see G1lien) + if (uri.startsWith('web+june://') || uri.startsWith('g1://')) { + protocol = 'g1:'; + uri = uri.replace(/^(g1|web+june):\/\//, 'http:'); } var parser = document.createElement('a'); -- GitLab