mirror of
https://github.com/nextcloud/passman.git
synced 2025-09-12 07:54:45 +08:00
Merge pull request #534 from nextcloud/fix/noid/icondisplay
Fix/noid/icondisplay
This commit is contained in:
commit
1d15d253de
8 changed files with 97 additions and 54 deletions
|
@ -78,6 +78,7 @@ return [
|
||||||
|
|
||||||
|
|
||||||
#Icons
|
#Icons
|
||||||
|
['name' => 'icon#getSingleIcon', 'url' => '/api/v2/geticon/{base64Url}', 'verb' => 'GET'],
|
||||||
['name' => 'icon#getIcon', 'url' => '/api/v2/icon/{base64Url}', 'verb' => 'GET'],
|
['name' => 'icon#getIcon', 'url' => '/api/v2/icon/{base64Url}', 'verb' => 'GET'],
|
||||||
['name' => 'icon#getIcon', 'url' => '/api/v2/icon/{base64Url}/{credentialId}', 'verb' => 'GET'],
|
['name' => 'icon#getIcon', 'url' => '/api/v2/icon/{base64Url}/{credentialId}', 'verb' => 'GET'],
|
||||||
['name' => 'icon#getLocalIconList', 'url' => '/api/v2/icon/list', 'verb' => 'GET'],
|
['name' => 'icon#getLocalIconList', 'url' => '/api/v2/icon/list', 'verb' => 'GET'],
|
||||||
|
|
|
@ -52,6 +52,28 @@ class IconController extends ApiController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
|
public function getSingleIcon($base64Url) {
|
||||||
|
$url = base64_decode(str_replace('_','/', $base64Url));
|
||||||
|
if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {
|
||||||
|
$url = "http://" . $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$icon = new IconService($url);
|
||||||
|
|
||||||
|
if ($icon->icoExists) {
|
||||||
|
$icon_json['type']= $icon->icoType;
|
||||||
|
$icon_json['content']= base64_encode($icon->icoData);
|
||||||
|
return new JSONResponse($icon_json);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JSONResponse();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @NoCSRFRequired
|
* @NoCSRFRequired
|
||||||
|
|
|
@ -143,6 +143,10 @@ class TranslationController extends ApiController {
|
||||||
'pick.icon.search' => $this->trans->t('Search icons'),
|
'pick.icon.search' => $this->trans->t('Search icons'),
|
||||||
'pick.icon.custom.label' => $this->trans->t('Upload a custom icon:'),
|
'pick.icon.custom.label' => $this->trans->t('Upload a custom icon:'),
|
||||||
'use.icon' => $this->trans->t('Use this icon'),
|
'use.icon' => $this->trans->t('Use this icon'),
|
||||||
|
'use.icon.delete' => $this->trans->t('Delete current icon'),
|
||||||
|
'use.icon.refresh' => $this->trans->t('Get icon from page'),
|
||||||
|
'use.icon.refresh.trying' => $this->trans->t('This may take a few seconds...'),
|
||||||
|
'use.icon.refresh.error' => $this->trans->t('There was an error fetching the icon!'),
|
||||||
'selected.icon' => $this->trans->t('Selected icon'),
|
'selected.icon' => $this->trans->t('Selected icon'),
|
||||||
|
|
||||||
// templates/views/partials/edit_credential/custom_fields.html
|
// templates/views/partials/edit_credential/custom_fields.html
|
||||||
|
|
|
@ -370,19 +370,6 @@
|
||||||
$scope.updateExistingListWithCredential(updated_cred);
|
$scope.updateExistingListWithCredential(updated_cred);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$scope.refreshListWithSaved();
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.refreshListWithSaved = function () {
|
|
||||||
var current_vault = $rootScope.vaultCache[$scope.active_vault.guid];
|
|
||||||
var cv_credentials = current_vault.credentials;
|
|
||||||
for (var i = 0; i < cv_credentials.length; i++) {
|
|
||||||
if (cv_credentials[i].credential_id === $scope.storedCredential.credential_id) {
|
|
||||||
cv_credentials[i] = $scope.storedCredential;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current_vault.credentials=cv_credentials;
|
|
||||||
$rootScope.vaultCache[$scope.active_vault.guid] = current_vault;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.updateExistingListWithCredential = function (credential) {
|
$scope.updateExistingListWithCredential = function (credential) {
|
||||||
|
@ -395,14 +382,13 @@
|
||||||
}
|
}
|
||||||
credential.tags_raw = credential.tags;
|
credential.tags_raw = credential.tags;
|
||||||
|
|
||||||
|
|
||||||
var found=false;
|
var found=false;
|
||||||
var credList=$rootScope.vaultCache[$scope.active_vault.guid].credentials;
|
var credList=$rootScope.vaultCache[$scope.active_vault.guid].credentials;
|
||||||
for (var i = 0; i < credList.length; i++) {
|
for (var i = 0; i < credList.length; i++) {
|
||||||
if (credList[i].credential_id === credential.credential_id) {
|
if (credList[i].credential_id === credential.credential_id) {
|
||||||
$rootScope.vaultCache[$scope.active_vault.guid].credentials[i]=credential;
|
$rootScope.vaultCache[$scope.active_vault.guid].credentials[i]=credential;
|
||||||
found=true;
|
found=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!found){
|
if(!found){
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
* # passwordGen
|
* # passwordGen
|
||||||
*/
|
*/
|
||||||
angular.module('passmanApp').directive('iconPicker', [
|
angular.module('passmanApp').directive('iconPicker', [
|
||||||
'$window', 'IconService', '$http', function($window, IconService, $http) {
|
'$window', 'IconService', '$http', 'NotificationService','$translate', function($window, IconService, $http, NotificationService, $translate) {
|
||||||
return {
|
return {
|
||||||
templateUrl: 'views/partials/icon-picker.html',
|
templateUrl: 'views/partials/icon-picker.html',
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
|
@ -95,8 +95,6 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$('#iconPicker-CustomIcon').on('change', function(ev) {
|
$('#iconPicker-CustomIcon').on('change', function(ev) {
|
||||||
|
|
||||||
console.log("upload");
|
|
||||||
scope.customIcon = {};
|
scope.customIcon = {};
|
||||||
|
|
||||||
var f = ev.target.files[0];
|
var f = ev.target.files[0];
|
||||||
|
@ -110,26 +108,44 @@
|
||||||
fr.readAsDataURL(f);
|
fr.readAsDataURL(f);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
scope.deleteIcon = function() {
|
||||||
|
delete scope.credential.icon.type;
|
||||||
|
delete scope.credential.icon.content;
|
||||||
|
delete scope.credential.icon;
|
||||||
|
$('#iconPicker').dialog('close');
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.refreshUrlIcon = function(){
|
||||||
|
NotificationService.showNotification($translate.instant('use.icon.refresh.trying'), 5000);
|
||||||
|
var queryUrl = OC.generateUrl('apps/passman/api/v2/geticon/'+btoa(scope.credential.url));
|
||||||
|
$http.get(queryUrl).then(function (response) {
|
||||||
|
if(typeof response.data.content !== 'undefined'){
|
||||||
|
scope.customIcon = {};
|
||||||
|
scope.customIcon.data='data:image/'+response.data.type+';base64,'+response.data.content;
|
||||||
|
}else{
|
||||||
|
NotificationService.showNotification($translate.instant('use.icon.refresh.error'), 5000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
scope.useIcon = function() {
|
scope.useIcon = function() {
|
||||||
|
|
||||||
if(scope.customIcon){
|
if(scope.customIcon){
|
||||||
var data = scope.customIcon.data;
|
var data = scope.customIcon.data;
|
||||||
scope.credential.icon.type = data.substring(data.lastIndexOf(":")+1,data.lastIndexOf(";"));
|
scope.credential.icon.type = data.substring(data.lastIndexOf(":")+1,data.lastIndexOf(";"));
|
||||||
scope.credential.icon.content = data.substring(data.lastIndexOf(",")+1, data.length);
|
scope.credential.icon.content = data.substring(data.lastIndexOf(",")+1, data.length);
|
||||||
$('#iconPicker').dialog('close');
|
}else{
|
||||||
return;
|
$http.get(scope.selectedIcon.url).then(function(result) {
|
||||||
|
var base64Data = window.btoa(result.data);
|
||||||
|
var mimeType = 'svg+xml';
|
||||||
|
if(!scope.credential.icon){
|
||||||
|
scope.credential.icon = {};
|
||||||
|
}
|
||||||
|
scope.credential.icon.type = mimeType;
|
||||||
|
scope.credential.icon.content = base64Data;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
$('#iconPicker').dialog('close');
|
||||||
$http.get(scope.selectedIcon.url).then(function(result) {
|
|
||||||
var base64Data = window.btoa(result.data);
|
|
||||||
var mimeType = 'svg+xml';
|
|
||||||
if(!scope.credential.icon){
|
|
||||||
scope.credential.icon = {};
|
|
||||||
}
|
|
||||||
scope.credential.icon.type = mimeType;
|
|
||||||
scope.credential.icon.content = base64Data;
|
|
||||||
$('#iconPicker').dialog('close');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$(element).click(function() {
|
$(element).click(function() {
|
||||||
|
|
|
@ -696,8 +696,11 @@
|
||||||
|
|
||||||
.icon-label {
|
.icon-label {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
input {
|
input {
|
||||||
width: calc(100% - 28px) !important;
|
//width: calc(100% - 28px) !important;
|
||||||
|
//width: 100% !important;
|
||||||
|
//width: inherit !important;
|
||||||
float: left;
|
float: left;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: #555;
|
color: #555;
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
<div class="cell icon-category-auth"></div>
|
<div class="cell icon-category-auth" ng-if="!credential.url && !credential.icon"></div>
|
||||||
|
|
||||||
|
<div class="cell" ng-if="credential.url || credential.icon">
|
||||||
|
<span class="icon">
|
||||||
|
<credential-icon credential="credential"></credential-icon>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="display: none" id="iconPicker" title="{{ 'pick.icon' | translate }}">
|
<div style="display: none" id="iconPicker" title="{{ 'pick.icon' | translate }}">
|
||||||
<div class="iconList">
|
<div class="iconList">
|
||||||
<div ng-repeat="(groupName, icons) in iconGroups">
|
<div ng-repeat="(groupName, icons) in iconGroups">
|
||||||
<div ng-click="expanded = !expanded" ng-init="expanded=true">
|
<div ng-click="expanded = !expanded" ng-init="expanded=true">
|
||||||
<div class="icon-triangle-s arrow" ng-class="{ 'icon-triangle-e': !expanded , 'icon-triangle-s': expanded }"></div>
|
<div class="icon-triangle-s arrow" ng-class="{ 'icon-triangle-e': !expanded , 'icon-triangle-s': expanded }"></div>
|
||||||
|
@ -13,22 +20,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="iconModifier">
|
<div class="iconModifier">
|
||||||
<input id="iconPicker-Search" class="iconSearch" type="text" placeholder="{{ 'pick.icon.search' | translate }}">
|
<input id="iconPicker-Search" class="iconSearch" type="text" placeholder="{{ 'pick.icon.search' | translate }}">
|
||||||
<label for="iconPicker-CustomIcon">{{ 'pick.icon.custom.label' | translate }}<label>
|
<label for="iconPicker-CustomIcon">{{ 'pick.icon.custom.label' | translate }}</label>
|
||||||
<input id="iconPicker-CustomIcon" class="iconSearch" type="file"/>
|
<input id="iconPicker-CustomIcon" class="iconSearch" type="file"/>
|
||||||
<!--
|
<!--
|
||||||
<div ng-repeat="(groupName, icons) in iconGroups">
|
<div ng-repeat="(groupName, icons) in iconGroups">
|
||||||
<a ng-click="jumpToGroup(groupName)">{{groupName}}</a>
|
<a ng-click="jumpToGroup(groupName)">{{groupName}}</a>
|
||||||
</div>-->
|
</div>-->
|
||||||
<div ng-if="selectedIcon || customIcon">
|
<div ng-if="selectedIcon || customIcon">
|
||||||
{{ 'selected.icon' | translate}}: <br />
|
{{ 'selected.icon' | translate}}: <br />
|
||||||
|
|
||||||
<img ng-src="{{selectedIcon.url}}" height="32" ng-if="!customIcon">
|
<img ng-src="{{selectedIcon.url}}" height="32" ng-if="!customIcon">
|
||||||
<img src="{{customIcon.data}}" height="32" ng-if="customIcon">
|
<img src="{{customIcon.data}}" height="32" ng-if="customIcon">
|
||||||
<br />
|
<br />
|
||||||
<button ng-click="useIcon()">{{ 'use.icon' | translate}}</button>
|
<button ng-click="useIcon()">{{ 'use.icon' | translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div >
|
||||||
|
<button ng-click="deleteIcon()" ng-if="credential.icon">{{ 'use.icon.delete' | translate}}</button>
|
||||||
|
<button ng-click="refreshUrlIcon()">{{ 'use.icon.refresh' | translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -48,10 +48,10 @@
|
||||||
<span class="tag" ng-repeat="tag in credential.tags_raw">{{ ::tag.text}}</span>
|
<span class="tag" ng-repeat="tag in credential.tags_raw">{{ ::tag.text}}</span>
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
<span class="icon" ng-if="credential.url">
|
<span class="icon" ng-if="credential.url || credential.icon">
|
||||||
<credential-icon credential="credential"></credential-icon>
|
<credential-icon credential="credential"></credential-icon>
|
||||||
</span>
|
</span>
|
||||||
<span class="icon" ng-if="!credential.url">
|
<span class="icon" ng-if="!credential.url && !credential.icon">
|
||||||
<i class="fa fa-lock" ng-if="!credential.acl && !credential.shared_key"></i>
|
<i class="fa fa-lock" ng-if="!credential.acl && !credential.shared_key"></i>
|
||||||
<i class="fa fa-share-alt" ng-if="credential.acl"></i>
|
<i class="fa fa-share-alt" ng-if="credential.acl"></i>
|
||||||
<i class="fa fa-share-alt-square" ng-if="credential.shared_key"> </i>
|
<i class="fa fa-share-alt-square" ng-if="credential.shared_key"> </i>
|
||||||
|
@ -145,10 +145,10 @@
|
||||||
<span class="close icon-close" ng-click="closeSelected()" alt="Close"></span>
|
<span class="close icon-close" ng-click="closeSelected()" alt="Close"></span>
|
||||||
|
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<span class="icon sidebar-icon" ng-if="selectedCredential.url">
|
<span class="icon sidebar-icon" ng-if="selectedCredential.url || credential.icon">
|
||||||
<credential-icon credential="selectedCredential"></credential-icon>
|
<credential-icon credential="selectedCredential"></credential-icon>
|
||||||
</span>
|
</span>
|
||||||
<span class="icon sidebar-icon" ng-if="!selectedCredential.url">
|
<span class="icon sidebar-icon" ng-if="!selectedCredential.url && !credential.icon">
|
||||||
<credential-icon credential="selectedCredential"></credential-icon>
|
<credential-icon credential="selectedCredential"></credential-icon>
|
||||||
</span>
|
</span>
|
||||||
<h2 class="sidebar-label">{{selectedCredential.label}}</h2>
|
<h2 class="sidebar-label">{{selectedCredential.label}}</h2>
|
||||||
|
|
Loading…
Add table
Reference in a new issue