mirror of
https://github.com/JanGross/quicknotes.git
synced 2025-11-30 23:37:16 +01:00
Merge pull request #36 from matiasdelellis/shared-notes
Fix backend to shared notes, and initial fronted code.
This commit is contained in:
@@ -5,6 +5,28 @@ return ['resources' =>
|
|||||||
'noteApi' => ['url' => '/api/v1/notes']
|
'noteApi' => ['url' => '/api/v1/notes']
|
||||||
],
|
],
|
||||||
'routes' => [
|
'routes' => [
|
||||||
['name' => 'page#index', 'url' => '/', 'verb' => 'GET']
|
// Main page
|
||||||
|
[
|
||||||
|
'name' => 'page#index',
|
||||||
|
'url' => '/',
|
||||||
|
'verb' => 'GET'
|
||||||
|
],
|
||||||
|
// Share
|
||||||
|
[
|
||||||
|
'name' => 'share#destroy',
|
||||||
|
'url' => '/share/{noteId}',
|
||||||
|
'verb' => 'DELETE'
|
||||||
|
],
|
||||||
|
// User Settings
|
||||||
|
[
|
||||||
|
'name' => 'settings#setUserValue',
|
||||||
|
'url' => '/setuservalue',
|
||||||
|
'verb' => 'POST'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'settings#getUserValue',
|
||||||
|
'url' => '/getuservalue',
|
||||||
|
'verb' => 'GET'
|
||||||
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -226,7 +226,8 @@ div[contenteditable="true"] {
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-options {
|
.note-options,
|
||||||
|
.note-disable-options {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
}
|
}
|
||||||
@@ -249,6 +250,7 @@ div[contenteditable="true"] {
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.slim-share,
|
||||||
.slim-tag {
|
.slim-tag {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -260,14 +262,17 @@ div[contenteditable="true"] {
|
|||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.slim-share:hover,
|
||||||
.slim-tag:hover {
|
.slim-tag:hover {
|
||||||
background-color: rgba(0,0,0,0.12);
|
background-color: rgba(0,0,0,0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-tags {
|
.note-shares > .slim-share,
|
||||||
margin-top: 8px;
|
.note-tags > .slim-tag {
|
||||||
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Restore defaults select2 rules */
|
/* Restore defaults select2 rules */
|
||||||
|
|
||||||
.select2-container-multi
|
.select2-container-multi
|
||||||
@@ -294,6 +299,10 @@ div[contenteditable="true"] {
|
|||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.select2-container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/* Modal Content */
|
/* Modal Content */
|
||||||
|
|
||||||
.modal-content {
|
.modal-content {
|
||||||
|
|||||||
110
js/qn-dialogs.js
110
js/qn-dialogs.js
@@ -56,6 +56,9 @@ const QnDialogs = {
|
|||||||
data.push({id: item.id, text: item.name});
|
data.push({id: item.id, text: item.name});
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
|
},
|
||||||
|
formatNoMatches: function() {
|
||||||
|
return t('quicknotes', 'No tags found');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -125,6 +128,113 @@ const QnDialogs = {
|
|||||||
$('.select2-input').focus();
|
$('.select2-input').focus();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
shares: function (availableUsers, selectedUsers, callback) {
|
||||||
|
return $.when(this._getMessageTemplate()).then(function ($tmpl) {
|
||||||
|
var dialogName = 'qn-dialog-content';
|
||||||
|
var dialogId = '#' + dialogName;
|
||||||
|
var $dlg = $tmpl.octemplate({
|
||||||
|
dialog_name: dialogName,
|
||||||
|
title: t('quicknotes', 'Share note'),
|
||||||
|
message: t('quicknotes', 'Select the users to share. By default you only share the note. Attachments should be shared from files so they can view it.'),
|
||||||
|
type: 'none'
|
||||||
|
});
|
||||||
|
|
||||||
|
var input = $('<input/>');
|
||||||
|
input.attr('type', 'text');
|
||||||
|
input.attr('id', dialogName + '-input');
|
||||||
|
input.attr('multiple', 'multiple');
|
||||||
|
|
||||||
|
$dlg.append(input);
|
||||||
|
$('body').append($dlg);
|
||||||
|
|
||||||
|
input.select2({
|
||||||
|
placeholder: t('quicknotes', 'Select the users to share'),
|
||||||
|
multiple: true,
|
||||||
|
allowClear: true,
|
||||||
|
toggleSelect: true,
|
||||||
|
createSearchChoice: function(params) {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
tags: function () {
|
||||||
|
var data = [];
|
||||||
|
availableUsers.forEach(function (item, index) {
|
||||||
|
// Select2 expect id, text.
|
||||||
|
data.push({id: item, text: item});
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
formatNoMatches: function() {
|
||||||
|
return t('quicknotes', 'No user found');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
input.val(selectedUsers.map(function (value) { return value.name }));
|
||||||
|
input.trigger("change");
|
||||||
|
|
||||||
|
$('.select2-input').on("keyup", function (event) {
|
||||||
|
if (event.keyCode === 27) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
input.select2('close');
|
||||||
|
if (callback !== undefined) {
|
||||||
|
callback(false, []);
|
||||||
|
}
|
||||||
|
$(dialogId).ocdialog('close');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// wrap callback in _.once():
|
||||||
|
// only call callback once and not twice (button handler and close
|
||||||
|
// event) but call it for the close event, if ESC or the x is hit
|
||||||
|
if (callback !== undefined) {
|
||||||
|
callback = _.once(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttonlist = [{
|
||||||
|
text: t('quicknotes', 'Cancel'),
|
||||||
|
click: function () {
|
||||||
|
input.select2('close');
|
||||||
|
if (callback !== undefined) {
|
||||||
|
callback(false, []);
|
||||||
|
}
|
||||||
|
$(dialogId).ocdialog('close');
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
text: t('quicknotes', 'Done'),
|
||||||
|
click: function () {
|
||||||
|
input.select2('close');
|
||||||
|
if (callback !== undefined) {
|
||||||
|
var users = [];
|
||||||
|
// Quicknotes shares expect id, shared_user
|
||||||
|
newUsers = input.select2("data");
|
||||||
|
newUsers.forEach(function (item) {
|
||||||
|
item['shared_user'] = item.text;
|
||||||
|
users.push(item);
|
||||||
|
});
|
||||||
|
callback(true, users);
|
||||||
|
}
|
||||||
|
$(dialogId).ocdialog('close');
|
||||||
|
},
|
||||||
|
defaultButton: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
$(dialogId).ocdialog({
|
||||||
|
closeOnEscape: false,
|
||||||
|
modal: true,
|
||||||
|
buttons: buttonlist,
|
||||||
|
close: function () {
|
||||||
|
input.select2("close");
|
||||||
|
// callback is already fired if Yes/No is clicked directly
|
||||||
|
if (callback !== undefined) {
|
||||||
|
callback(false, input.val());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.select2-input').focus();
|
||||||
|
});
|
||||||
|
},
|
||||||
_getMessageTemplate: function () {
|
_getMessageTemplate: function () {
|
||||||
var defer = $.Deferred();
|
var defer = $.Deferred();
|
||||||
if (!this.$messageTemplate) {
|
if (!this.$messageTemplate) {
|
||||||
|
|||||||
253
js/script.js
253
js/script.js
@@ -29,6 +29,9 @@ var Notes = function (baseUrl) {
|
|||||||
this._baseUrl = baseUrl;
|
this._baseUrl = baseUrl;
|
||||||
this._notes = [];
|
this._notes = [];
|
||||||
this._loaded = false;
|
this._loaded = false;
|
||||||
|
|
||||||
|
this._usersSharing = [];
|
||||||
|
this._loadUsersSharing();
|
||||||
};
|
};
|
||||||
|
|
||||||
Notes.prototype = {
|
Notes.prototype = {
|
||||||
@@ -71,6 +74,9 @@ Notes.prototype = {
|
|||||||
});
|
});
|
||||||
return Ccolors;
|
return Ccolors;
|
||||||
},
|
},
|
||||||
|
getUsersSharing: function () {
|
||||||
|
return this._usersSharing;
|
||||||
|
},
|
||||||
// Get the tags used in the notes
|
// Get the tags used in the notes
|
||||||
getTags: function () {
|
getTags: function () {
|
||||||
var tags = [];
|
var tags = [];
|
||||||
@@ -136,6 +142,42 @@ Notes.prototype = {
|
|||||||
deferred.reject();
|
deferred.reject();
|
||||||
});
|
});
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
|
},
|
||||||
|
// Delete shared note.
|
||||||
|
forgetShare: function (note) {
|
||||||
|
var self = this;
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
$.ajax({
|
||||||
|
url: OC.generateUrl('/apps/quicknotes/share') + '/' + note.id,
|
||||||
|
method: 'DELETE'
|
||||||
|
}).done(function () {
|
||||||
|
var index = self._notes.findIndex((aNote) => aNote.id === note.id);
|
||||||
|
self._notes.splice(index, 1);
|
||||||
|
deferred.resolve();
|
||||||
|
}).fail(function () {
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
return deferred.promise();
|
||||||
|
},
|
||||||
|
// Get the users to share in the notes
|
||||||
|
_loadUsersSharing: function () {
|
||||||
|
var self = this;
|
||||||
|
$.get(OC.linkToOCS('apps/files_sharing/api/v1/', 1) + 'sharees', {
|
||||||
|
format: 'json',
|
||||||
|
perPage: 50,
|
||||||
|
itemType: 1
|
||||||
|
}).done(function (shares) {
|
||||||
|
var users = [];
|
||||||
|
$.each(shares.ocs.data.exact.users, function(index, user) {
|
||||||
|
users.push(user.value.shareWith);
|
||||||
|
});
|
||||||
|
$.each(shares.ocs.data.users, function(index, user) {
|
||||||
|
users.push(user.value.shareWith);
|
||||||
|
});
|
||||||
|
self._usersSharing = users;
|
||||||
|
}).fail(function () {
|
||||||
|
console.error("Could not get users to share.");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -164,11 +206,12 @@ View.prototype = {
|
|||||||
this._editableContent(note.content);
|
this._editableContent(note.content);
|
||||||
this._editablePinned(note.ispinned);
|
this._editablePinned(note.ispinned);
|
||||||
this._editableColor(note.color);
|
this._editableColor(note.color);
|
||||||
|
this._editableShares(note.shared_with, note.shared_by);
|
||||||
this._editableTags(note.tags);
|
this._editableTags(note.tags);
|
||||||
this._editableAttachts(note.attachts);
|
this._editableAttachts(note.attachts, !note.is_shared);
|
||||||
|
|
||||||
// Create medium div editor.
|
// Create medium div editor.
|
||||||
this._initEditor();
|
this._isEditable(!note.is_shared);
|
||||||
|
|
||||||
// Show modal editor
|
// Show modal editor
|
||||||
this._showEditor(id);
|
this._showEditor(id);
|
||||||
@@ -182,7 +225,8 @@ View.prototype = {
|
|||||||
attachts: this._editableAttachts(),
|
attachts: this._editableAttachts(),
|
||||||
color: this._editableColor(),
|
color: this._editableColor(),
|
||||||
pinned: this._editablePinned(),
|
pinned: this._editablePinned(),
|
||||||
tags: this._editableTags()
|
tags: this._editableTags(),
|
||||||
|
shares: this._editableShares()
|
||||||
};
|
};
|
||||||
var self = this;
|
var self = this;
|
||||||
this._notes.update(fakeNote).done(function (note) {
|
this._notes.update(fakeNote).done(function (note) {
|
||||||
@@ -304,6 +348,7 @@ View.prototype = {
|
|||||||
t('quicknotes', 'Delete note'),
|
t('quicknotes', 'Delete note'),
|
||||||
function(result) {
|
function(result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
|
if (!note.is_shared) {
|
||||||
self._notes.remove(note).done(function () {
|
self._notes.remove(note).done(function () {
|
||||||
if (self._notes.length() > 0) {
|
if (self._notes.length() > 0) {
|
||||||
$(".notes-grid").isotope('remove', gridnote.parent())
|
$(".notes-grid").isotope('remove', gridnote.parent())
|
||||||
@@ -316,6 +361,20 @@ View.prototype = {
|
|||||||
}).fail(function () {
|
}).fail(function () {
|
||||||
alert('Could not delete note, not found');
|
alert('Could not delete note, not found');
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
self._notes.forgetShare(note).done(function () {
|
||||||
|
if (self._notes.length() > 0) {
|
||||||
|
$(".notes-grid").isotope('remove', gridnote.parent())
|
||||||
|
.isotope('layout');
|
||||||
|
self.showAll();
|
||||||
|
self.renderNavigation();
|
||||||
|
} else {
|
||||||
|
self.render();
|
||||||
|
}
|
||||||
|
}).fail(function () {
|
||||||
|
alert('Could not delete note, not found');
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
true
|
true
|
||||||
@@ -454,6 +513,20 @@ View.prototype = {
|
|||||||
$('#modal-note-div #tag-button').trigger( "click");
|
$('#modal-note-div #tag-button').trigger( "click");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// handle tags button.
|
||||||
|
$('#modal-note-div #share-button').click(function (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
QnDialogs.shares(
|
||||||
|
self._notes.getUsersSharing(),
|
||||||
|
self._editableShares(),
|
||||||
|
function(result, newShares) {
|
||||||
|
if (result === true) {
|
||||||
|
self._editableShares(newShares, []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// handle attach button.
|
// handle attach button.
|
||||||
$('#modal-note-div #attach-button').click(function (event) {
|
$('#modal-note-div #attach-button').click(function (event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@@ -465,7 +538,7 @@ View.prototype = {
|
|||||||
preview_url: OC.generateUrl('core') + '/preview.png?file=' + encodeURI(datapath) + '&x=512&y=512',
|
preview_url: OC.generateUrl('core') + '/preview.png?file=' + encodeURI(datapath) + '&x=512&y=512',
|
||||||
redirect_url: OC.generateUrl('/apps/files/?dir={dir}&scrollto={scrollto}', {dir: fileInfo.path, scrollto: fileInfo.name})
|
redirect_url: OC.generateUrl('/apps/files/?dir={dir}&scrollto={scrollto}', {dir: fileInfo.path, scrollto: fileInfo.name})
|
||||||
});
|
});
|
||||||
self._editableAttachts(attachts);
|
self._editableAttachts(attachts, true);
|
||||||
}).fail(() => {
|
}).fail(() => {
|
||||||
console.log("ERRORRR");
|
console.log("ERRORRR");
|
||||||
});
|
});
|
||||||
@@ -483,13 +556,16 @@ View.prototype = {
|
|||||||
if (result === true) {
|
if (result === true) {
|
||||||
self._editableTags(newTags);
|
self._editableTags(newTags);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
true,
|
|
||||||
t('quicknotes', 'Tags'),
|
|
||||||
false
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// handle cancel editing notes.
|
||||||
|
$('#modal-note-div #close-button').click(function (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
self.cancelEdit();
|
||||||
|
});
|
||||||
|
|
||||||
// handle cancel editing notes.
|
// handle cancel editing notes.
|
||||||
$('#modal-note-div #cancel-button').click(function (event) {
|
$('#modal-note-div #cancel-button').click(function (event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@@ -516,36 +592,13 @@ View.prototype = {
|
|||||||
|
|
||||||
$('#app-navigation ul').html(html);
|
$('#app-navigation ul').html(html);
|
||||||
|
|
||||||
// show all notes
|
/* Create a new note */
|
||||||
$('#all-notes').click(function () {
|
|
||||||
$('.notes-grid').isotope({ filter: '*'});
|
|
||||||
|
|
||||||
var oldColorTool = $('#app-navigation .circle-toolbar.icon-checkmark');
|
|
||||||
$.each(oldColorTool, function(i, oct) {
|
|
||||||
$(oct).removeClass('icon-checkmark');
|
|
||||||
});
|
|
||||||
$('#app-navigation .any-color').addClass('icon-checkmark');
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#shared-with-you').click(function () {
|
|
||||||
$('.notes-grid').isotope({ filter: function() {
|
|
||||||
return $(this).children().hasClass('shared');
|
|
||||||
} });
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#shared-by-you').click(function () {
|
|
||||||
$('.notes-grid').isotope({ filter: function() {
|
|
||||||
return $(this).children().hasClass('shareowner');
|
|
||||||
} });
|
|
||||||
});
|
|
||||||
|
|
||||||
// create a new note
|
|
||||||
var self = this;
|
var self = this;
|
||||||
$('#new-note').click(function () {
|
$('#new-note').click(function () {
|
||||||
var fakenote = {
|
var fakenote = {
|
||||||
title: t('quicknotes', 'New note'),
|
title: t('quicknotes', 'New note'),
|
||||||
content: '',
|
content: ''
|
||||||
color: '#F7EB96'
|
|
||||||
};
|
};
|
||||||
self._notes.create(fakenote).done(function(note) {
|
self._notes.create(fakenote).done(function(note) {
|
||||||
if (self._notes.length() > 1) {
|
if (self._notes.length() > 1) {
|
||||||
@@ -564,6 +617,38 @@ View.prototype = {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Show all notes */
|
||||||
|
|
||||||
|
$('#all-notes').click(function () {
|
||||||
|
$('.notes-grid').isotope({ filter: '*'});
|
||||||
|
|
||||||
|
var oldColorTool = $('#colors-folder .circle-toolbar.icon-checkmark');
|
||||||
|
$.each(oldColorTool, function(i, oct) {
|
||||||
|
$(oct).removeClass('icon-checkmark');
|
||||||
|
});
|
||||||
|
$('#app-navigation .any-color').addClass('icon-checkmark');
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Shares Navigation */
|
||||||
|
|
||||||
|
$('#shared-folder').click(function () {
|
||||||
|
$(this).toggleClass("open");
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#shared-with-you').click(function (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
$('.notes-grid').isotope({ filter: function() {
|
||||||
|
return $(this).children().hasClass('shared');
|
||||||
|
} });
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#shared-by-you').click(function (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
$('.notes-grid').isotope({ filter: function() {
|
||||||
|
return $(this).children().hasClass('shareowner');
|
||||||
|
} });
|
||||||
|
});
|
||||||
|
|
||||||
/* Colors Navigation */
|
/* Colors Navigation */
|
||||||
|
|
||||||
$('#colors-folder').click(function () {
|
$('#colors-folder').click(function () {
|
||||||
@@ -574,9 +659,9 @@ View.prototype = {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#app-navigation .circle-toolbar').click(function (event) {
|
$('#colors-folder .circle-toolbar').click(function (event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
var oldColorTool = $('#app-navigation .circle-toolbar.icon-checkmark');
|
var oldColorTool = $('#colors-folder .circle-toolbar.icon-checkmark');
|
||||||
$.each(oldColorTool, function(i, oct) {
|
$.each(oldColorTool, function(i, oct) {
|
||||||
$(oct).removeClass('icon-checkmark');
|
$(oct).removeClass('icon-checkmark');
|
||||||
});
|
});
|
||||||
@@ -636,8 +721,48 @@ View.prototype = {
|
|||||||
$(oct).removeClass('icon-checkmark');
|
$(oct).removeClass('icon-checkmark');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
|
},
|
||||||
|
renderSettings: function () {
|
||||||
|
/* Render view */
|
||||||
|
var html = Handlebars.templates['settings']({});
|
||||||
|
$('#app-settings-content').html(html);
|
||||||
|
var self = this;
|
||||||
|
$.get(OC.generateUrl('apps/quicknotes/getuservalue'), {'type': 'default_color'})
|
||||||
|
.done(function (response) {
|
||||||
|
var color = response.value;;
|
||||||
|
var colors = $("#setting-defaul-color")[0].getElementsByClassName("circle-toolbar");
|
||||||
|
$.each(colors, function(i, c) {
|
||||||
|
if (color === self._colorToHex(c.style.backgroundColor)) {
|
||||||
|
c.className += " icon-checkmark";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Settings */
|
||||||
|
|
||||||
|
$("#app-settings-content").off();
|
||||||
|
|
||||||
|
$('#app-settings-content').on('click', '.circle-toolbar', function (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
var currentColor = $(this);
|
||||||
|
var color = self._colorToHex(currentColor.css("background-color"));
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: OC.generateUrl('apps/quicknotes/setuservalue'),
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
'type': 'default_color',
|
||||||
|
'value': color
|
||||||
|
},
|
||||||
|
success: function (response) {
|
||||||
|
$('#setting-defaul-color .circle-toolbar').removeClass('icon-checkmark');
|
||||||
|
currentColor.addClass('icon-checkmark');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Some 'private' functions as helpers.
|
* Some 'private' functions as helpers.
|
||||||
*/
|
*/
|
||||||
@@ -655,6 +780,25 @@ View.prototype = {
|
|||||||
|
|
||||||
return digits[1] + '#' + rgb.toString(16).toUpperCase();
|
return digits[1] + '#' + rgb.toString(16).toUpperCase();
|
||||||
},
|
},
|
||||||
|
_isEditable: function(editable) {
|
||||||
|
if (editable === undefined)
|
||||||
|
return $('#title-editable').prop('contenteditable');
|
||||||
|
else {
|
||||||
|
if (editable) {
|
||||||
|
$('#modal-note-div .icon-header-note').show();
|
||||||
|
$('#title-editable').prop('contenteditable', true);
|
||||||
|
$('#modal-note-div .note-options').show();
|
||||||
|
$('#modal-note-div .note-disable-options').hide();
|
||||||
|
this._initEditor();
|
||||||
|
} else {
|
||||||
|
$('#modal-note-div .icon-header-note').hide();
|
||||||
|
$('#title-editable').removeAttr("contentEditable");
|
||||||
|
$('#content-editable').removeAttr("contentEditable");
|
||||||
|
$('#modal-note-div .note-options').hide();
|
||||||
|
$('#modal-note-div .note-disable-options').show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
_editableId: function(id) {
|
_editableId: function(id) {
|
||||||
if (id === undefined)
|
if (id === undefined)
|
||||||
return $("#modal-note-div .quicknote").data('id');
|
return $("#modal-note-div .quicknote").data('id');
|
||||||
@@ -706,6 +850,19 @@ View.prototype = {
|
|||||||
$("#modal-note-div .quicknote").css("background-color", color);
|
$("#modal-note-div .quicknote").css("background-color", color);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
_editableShares: function(shared_with, shared_by) {
|
||||||
|
if (shared_with === undefined) {
|
||||||
|
return $("#modal-note-div .slim-share").toArray().map(function (value) {
|
||||||
|
return {
|
||||||
|
id: value.getAttribute('share-id'),
|
||||||
|
name: value.textContent.trim()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var html = Handlebars.templates['shares']({ shared_by: shared_by, shared_with: shared_with});
|
||||||
|
$("#modal-note-div .note-shares").replaceWith(html);
|
||||||
|
}
|
||||||
|
},
|
||||||
_editableTags: function(tags) {
|
_editableTags: function(tags) {
|
||||||
if (tags === undefined) {
|
if (tags === undefined) {
|
||||||
return $("#modal-note-div .slim-tag").toArray().map(function (value) {
|
return $("#modal-note-div .slim-tag").toArray().map(function (value) {
|
||||||
@@ -719,7 +876,7 @@ View.prototype = {
|
|||||||
$("#modal-note-div .note-tags").replaceWith(html);
|
$("#modal-note-div .note-tags").replaceWith(html);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_editableAttachts: function(attachts) {
|
_editableAttachts: function(attachts, can_delete) {
|
||||||
if (attachts === undefined) {
|
if (attachts === undefined) {
|
||||||
return $("#modal-note-div .note-attach").toArray().map(function (value) {
|
return $("#modal-note-div .note-attach").toArray().map(function (value) {
|
||||||
return {
|
return {
|
||||||
@@ -729,7 +886,7 @@ View.prototype = {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var html = Handlebars.templates['attachts']({ attachts: attachts});
|
var html = Handlebars.templates['attachts']({ attachts: attachts, can_delete: can_delete});
|
||||||
$("#modal-note-div .note-attachts").replaceWith(html);
|
$("#modal-note-div .note-attachts").replaceWith(html);
|
||||||
|
|
||||||
lozad('.attach-preview').observe();
|
lozad('.attach-preview').observe();
|
||||||
@@ -797,8 +954,10 @@ View.prototype = {
|
|||||||
this._editor = editor;
|
this._editor = editor;
|
||||||
},
|
},
|
||||||
_destroyEditor: function() {
|
_destroyEditor: function() {
|
||||||
|
if (this._editor != undefined) {
|
||||||
this._editor.destroy();
|
this._editor.destroy();
|
||||||
this._editor = undefined;
|
this._editor = undefined;
|
||||||
|
}
|
||||||
this._changed = false;
|
this._changed = false;
|
||||||
|
|
||||||
this._editableId(-1);
|
this._editableId(-1);
|
||||||
@@ -821,7 +980,6 @@ View.prototype = {
|
|||||||
"left" : note.offset().left,
|
"left" : note.offset().left,
|
||||||
"top" : note.offset().top,
|
"top" : note.offset().top,
|
||||||
"width" : note.width(),
|
"width" : note.width(),
|
||||||
"min-height": note.height(),
|
|
||||||
"height:" : "auto"
|
"height:" : "auto"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -893,6 +1051,7 @@ View.prototype = {
|
|||||||
render: function () {
|
render: function () {
|
||||||
this.renderNavigation();
|
this.renderNavigation();
|
||||||
this.renderContent();
|
this.renderContent();
|
||||||
|
this.renderSettings();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -926,6 +1085,19 @@ new OCA.Search(search, function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Helpers to handlebars
|
||||||
|
*/
|
||||||
|
|
||||||
|
Handlebars.registerHelper('tSW', function(user) {
|
||||||
|
return t('quicknotes', 'Shared with {user}', {user: user});
|
||||||
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('tSB', function(user) {
|
||||||
|
return t('quicknotes', 'Shared by {user}', {user: user});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create modules
|
* Create modules
|
||||||
*/
|
*/
|
||||||
@@ -941,8 +1113,7 @@ view.renderContent();
|
|||||||
* Loading notes and render final view.
|
* Loading notes and render final view.
|
||||||
*/
|
*/
|
||||||
notes.load().done(function () {
|
notes.load().done(function () {
|
||||||
view.renderNavigation();
|
view.render();
|
||||||
view.renderContent();
|
|
||||||
}).fail(function () {
|
}).fail(function () {
|
||||||
alert('Could not load notes');
|
alert('Could not load notes');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
<a target="_blank" href="{{redirect_url}}">
|
<a target="_blank" href="{{redirect_url}}">
|
||||||
<div class="attach-preview note-attach" attach-file-id="{{file_id}}" data-background-image="{{preview_url}}"/>
|
<div class="attach-preview note-attach" attach-file-id="{{file_id}}" data-background-image="{{preview_url}}"/>
|
||||||
</a>
|
</a>
|
||||||
|
{{#if ../can_delete}}
|
||||||
<div class="attach-remove icon-delete" title="{{t "quicknotes" "Delete attachment"}}"/>
|
<div class="attach-remove icon-delete" title="{{t "quicknotes" "Delete attachment"}}"/>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
@@ -8,6 +8,18 @@
|
|||||||
{{allNotesTxt}}
|
{{allNotesTxt}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li id="shared-folder" class="collapsible open">
|
||||||
|
<button class="collapse"></button>
|
||||||
|
<a href="#" class="icon-share svg">{{t "quicknotes" "Shared" }}</a>
|
||||||
|
<ul>
|
||||||
|
<li id="shared-by-you">
|
||||||
|
<a href="#" class="icon-share svg">{{t "quicknotes" "Shared with others" }}</a>
|
||||||
|
</li>
|
||||||
|
<li id="shared-with-you">
|
||||||
|
<a href="#" class="icon-share svg">{{t "quicknotes" "Shared with you" }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li id="colors-folder" class="collapsible open">
|
<li id="colors-folder" class="collapsible open">
|
||||||
<button class="collapse"></button>
|
<button class="collapse"></button>
|
||||||
<a href="#" class="icon-search svg">{{colorsTxt}}</a>
|
<a href="#" class="icon-search svg">{{colorsTxt}}</a>
|
||||||
|
|||||||
@@ -1,16 +1,5 @@
|
|||||||
<div class="note-grid-item">
|
<div class="note-grid-item">
|
||||||
<div class="quicknote noselect {{#if active}}note-active{{/if}} {{#if isshared}}shared{{/if}} {{#if sharedwith}}shareowner{{/if}}" style="background-color: {{color}}" data-id="{{ id }}" data-timestamp="{{ timestamp }}" >
|
<div class="quicknote noselect {{#if is_shared}}shared{{/if}} {{#if shared_with.length}}shareowner{{/if}}" style="background-color: {{color}}" data-id="{{ id }}" data-timestamp="{{ timestamp }}" >
|
||||||
{{#if isshared}}
|
|
||||||
<div>
|
|
||||||
<div class='icon-share shared-title' title="Shared by {{ userid }}"></div>
|
|
||||||
<div class='note-title'>
|
|
||||||
{{{ title }}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id='content' class='note-content'>
|
|
||||||
{{{ content }}}
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
<div class='note-header'>
|
<div class='note-header'>
|
||||||
<div class='note-attachts'>
|
<div class='note-attachts'>
|
||||||
{{#each attachts}}
|
{{#each attachts}}
|
||||||
@@ -28,11 +17,6 @@
|
|||||||
<div class="icon-header-note icon-pin hide-header-icon" title="{{t "quicknotes" "Pin note"}}"></div>
|
<div class="icon-header-note icon-pin hide-header-icon" title="{{t "quicknotes" "Pin note"}}"></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="icon-header-note icon-delete hide-header-icon icon-delete-note" title="{{t "quicknotes" "Delete note"}}"></div>
|
<div class="icon-header-note icon-delete hide-header-icon icon-delete-note" title="{{t "quicknotes" "Delete note"}}"></div>
|
||||||
<!--
|
|
||||||
{{#if sharedwith}}
|
|
||||||
<div class='icon-share shared-title-owner' title="Shared with {{ sharedwith }}"></div>
|
|
||||||
{{/if}}
|
|
||||||
-->
|
|
||||||
<div class='note-title'>
|
<div class='note-title'>
|
||||||
{{{ title }}}
|
{{{ title }}}
|
||||||
</div>
|
</div>
|
||||||
@@ -40,12 +24,16 @@
|
|||||||
<div class='note-content'>
|
<div class='note-content'>
|
||||||
{{{ content }}}
|
{{{ content }}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class='note-shares'>
|
||||||
|
{{#each shared_with}}
|
||||||
|
<div class="icon-user slim-share" share-id="{{ shared_user }}" title="Shared with {{ shared_user }}">{{{ shared_user }}}</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
<div class='note-tags'>
|
<div class='note-tags'>
|
||||||
{{#each tags}}
|
{{#each tags}}
|
||||||
<div class="icon-tag slim-tag" tag-id="{{ id }}">{{{ name }}}</div>
|
<div class="icon-tag slim-tag" tag-id="{{ id }}">{{{ name }}}</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -2,18 +2,7 @@
|
|||||||
<div id="notes-grid-div" class="notes-grid">
|
<div id="notes-grid-div" class="notes-grid">
|
||||||
{{#each notes}}
|
{{#each notes}}
|
||||||
<div class="note-grid-item">
|
<div class="note-grid-item">
|
||||||
<div class="quicknote noselect {{#if isshared}}shared{{/if}} {{#if sharedwith}}shareowner{{/if}}" style="background-color: {{color}}" data-id="{{ id }}" data-timestamp="{{ timestamp }}" >
|
<div class="quicknote noselect {{#if is_shared}}shared{{/if}} {{#if shared_with.length}}shareowner{{/if}}" style="background-color: {{color}}" data-id="{{ id }}" data-timestamp="{{ timestamp }}" >
|
||||||
{{#if isshared}}
|
|
||||||
<div>
|
|
||||||
<div class='icon-share shared-title' title="Shared by {{ userid }}"></div>
|
|
||||||
<div class='note-title'>
|
|
||||||
{{{ title }}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id='content' class='note-content'>
|
|
||||||
{{{ content }}}
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
<div class='note-header'>
|
<div class='note-header'>
|
||||||
<div class='note-attachts'>
|
<div class='note-attachts'>
|
||||||
{{#each attachts}}
|
{{#each attachts}}
|
||||||
@@ -25,17 +14,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class='note-body'>
|
<div class='note-body'>
|
||||||
<div>
|
<div>
|
||||||
|
{{#if is_shared}}
|
||||||
|
<div class="icon-header-note icon-share" title="{{tSB userid }}"></div>
|
||||||
|
<div class="icon-header-note icon-delete hide-header-icon icon-delete-note" title="{{t "quicknotes" "Delete note"}}"></div>
|
||||||
|
{{else}}
|
||||||
{{#if ispinned}}
|
{{#if ispinned}}
|
||||||
<div class="icon-header-note icon-pinned fixed-header-icon" title="{{t "quicknotes" "Unpin note"}}"></div>
|
<div class="icon-header-note icon-pinned fixed-header-icon" title="{{t "quicknotes" "Unpin note"}}"></div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="icon-header-note icon-pin hide-header-icon" title="{{t "quicknotes" "Pin note"}}"></div>
|
<div class="icon-header-note icon-pin hide-header-icon" title="{{t "quicknotes" "Pin note"}}"></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="icon-header-note icon-delete hide-header-icon icon-delete-note" title="{{t "quicknotes" "Delete note"}}"></div>
|
<div class="icon-header-note icon-delete hide-header-icon icon-delete-note" title="{{t "quicknotes" "Delete note"}}"></div>
|
||||||
<!--
|
|
||||||
{{#if sharedwith}}
|
|
||||||
<div class='icon-share shared-title-owner' title="Shared with {{ sharedwith }}"></div>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
-->
|
|
||||||
<div class='note-title'>
|
<div class='note-title'>
|
||||||
{{{ title }}}
|
{{{ title }}}
|
||||||
</div>
|
</div>
|
||||||
@@ -43,6 +32,11 @@
|
|||||||
<div class='note-content'>
|
<div class='note-content'>
|
||||||
{{{ content }}}
|
{{{ content }}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class='note-shares'>
|
||||||
|
{{#each shared_with}}
|
||||||
|
<div class="icon-user slim-share" share-id="{{ shared_user }}" title="{{tSW shared_user}}">{{{ shared_user }}}</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
<div class='note-tags'>
|
<div class='note-tags'>
|
||||||
{{#each tags}}
|
{{#each tags}}
|
||||||
<div class='icon-tag slim-tag' tag-id="{{ id }}">
|
<div class='icon-tag slim-tag' tag-id="{{ id }}">
|
||||||
@@ -51,7 +45,6 @@
|
|||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
@@ -68,6 +61,7 @@
|
|||||||
<div contenteditable="true" id='title-editable' class='note-title'></div>
|
<div contenteditable="true" id='title-editable' class='note-title'></div>
|
||||||
</div>
|
</div>
|
||||||
<div contenteditable="true" id='content-editable' class='note-content'></div>
|
<div contenteditable="true" id='content-editable' class='note-content'></div>
|
||||||
|
<div class='note-shares'></div>
|
||||||
<div class='note-tags'></div>
|
<div class='note-tags'></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="note-options">
|
<div class="note-options">
|
||||||
@@ -87,9 +81,9 @@
|
|||||||
<a href="#" class="circle-toolbar" style="background-color: #CECECE"></a>
|
<a href="#" class="circle-toolbar" style="background-color: #CECECE"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons-toolbar">
|
<div class="buttons-toolbar">
|
||||||
<!--
|
<button id='share-button' class='round-tool-button'>
|
||||||
<button id='share-button'><?php p($l->t('Share'));?></button>
|
<div class="icon-shared" title="{{t "quicknotes" "Share note"}}"></div>
|
||||||
-->
|
</button>
|
||||||
<button id='attach-button' class='round-tool-button'>
|
<button id='attach-button' class='round-tool-button'>
|
||||||
<div class="icon-picture" title="{{t "quicknotes" "Attach file"}}"></div>
|
<div class="icon-picture" title="{{t "quicknotes" "Attach file"}}"></div>
|
||||||
</button>
|
</button>
|
||||||
@@ -105,7 +99,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div style="clear: both;"></div>
|
<div style="clear: both;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="note-disable-options">
|
||||||
|
<div class="buttons-toolbar">
|
||||||
|
<button id='close-button'>{{t "quicknotes" "Close"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="clear: both;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
19
js/templates/settings.handlebars
Normal file
19
js/templates/settings.handlebars
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<div>
|
||||||
|
<label>{{t "quicknotes" "Default color for new notes"}}</label>
|
||||||
|
</div>
|
||||||
|
<div id="setting-defaul-color">
|
||||||
|
<div id="defaultColor" style="display: flex; justify-content: center;">
|
||||||
|
<div class="colors-toolbar">
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #F7EB96"></a>
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #88B7E3"></a>
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #C1ECB0"></a>
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #BFA6E9"></a>
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #DAF188"></a>
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #FF96AC"></a>
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #FCF66F"></a>
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #F2F1EF"></a>
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #C1D756"></a>
|
||||||
|
<a href="#" class="circle-toolbar" style="background-color: #CECECE"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
5
js/templates/shares.handlebars
Normal file
5
js/templates/shares.handlebars
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<div class='note-shares'>
|
||||||
|
{{#each shared_with}}
|
||||||
|
<div class="icon-user slim-share" share-id="{{ shared_user }}" title="{{tSW shared_user}}">{{{ shared_user }}}</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
@@ -91,7 +91,7 @@ class NoteController extends Controller {
|
|||||||
* @param string $content
|
* @param string $content
|
||||||
* @param string $color
|
* @param string $color
|
||||||
*/
|
*/
|
||||||
public function create($title, $content, $color = "#F7EB96") {
|
public function create($title, $content, $color = NULL) {
|
||||||
$note = $this->noteService->create($this->userId, $title, $content, $color);
|
$note = $this->noteService->create($this->userId, $title, $content, $color);
|
||||||
|
|
||||||
$etag = md5(json_encode($note));
|
$etag = md5(json_encode($note));
|
||||||
@@ -111,10 +111,11 @@ class NoteController extends Controller {
|
|||||||
* @param array $attachts
|
* @param array $attachts
|
||||||
* @param bool $pinned
|
* @param bool $pinned
|
||||||
* @param array $tags
|
* @param array $tags
|
||||||
|
* @param array $shares
|
||||||
* @param string $color
|
* @param string $color
|
||||||
*/
|
*/
|
||||||
public function update(int $id, string $title, string $content, array $attachts, bool $pinned, array $tags, string $color = "#F7EB96"): JSONResponse {
|
public function update(int $id, string $title, string $content, array $attachts, bool $pinned, array $tags, array $shares, string $color = "#F7EB96"): JSONResponse {
|
||||||
$note = $this->noteService->update($this->userId, $id, $title, $content, $attachts, $pinned, $tags, $color);
|
$note = $this->noteService->update($this->userId, $id, $title, $content, $attachts, $pinned, $tags, $shares, $color);
|
||||||
if (is_null($note)) {
|
if (is_null($note)) {
|
||||||
return new JSONResponse([], Http::STATUS_NOT_FOUND);
|
return new JSONResponse([], Http::STATUS_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|||||||
112
lib/Controller/SettingsController.php
Normal file
112
lib/Controller/SettingsController.php
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2020 Matias De lellis <mati86dl@gmail.com>
|
||||||
|
*
|
||||||
|
* @author Matias De lellis <mati86dl@gmail.com>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\QuickNotes\Controller;
|
||||||
|
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
use OCP\AppFramework\Http\JSONResponse;
|
||||||
|
use OCP\IRequest;
|
||||||
|
|
||||||
|
use OCA\QuickNotes\Service\SettingsService;
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsController extends Controller {
|
||||||
|
|
||||||
|
/** @var SettingsService */
|
||||||
|
private $settingsService;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $userId;
|
||||||
|
|
||||||
|
const STATE_OK = 0;
|
||||||
|
const STATE_FALSE = 1;
|
||||||
|
const STATE_SUCCESS = 2;
|
||||||
|
const STATE_ERROR = 3;
|
||||||
|
|
||||||
|
public function __construct ($appName,
|
||||||
|
IRequest $request,
|
||||||
|
SettingsService $settingsService,
|
||||||
|
$userId)
|
||||||
|
{
|
||||||
|
parent::__construct($appName, $request);
|
||||||
|
|
||||||
|
$this->appName = $appName;
|
||||||
|
$this->settingsService = $settingsService;
|
||||||
|
$this->userId = $userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @param $type
|
||||||
|
* @param $value
|
||||||
|
* @return JSONResponse
|
||||||
|
*/
|
||||||
|
public function setUserValue($type, $value) {
|
||||||
|
$status = self::STATE_SUCCESS;
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case SettingsService::COLOR_FOR_NEW_NOTES_KEY:
|
||||||
|
$this->settingsService->setColorForNewNotes($value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$status = self::STATE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response
|
||||||
|
$result = [
|
||||||
|
'status' => $status,
|
||||||
|
'value' => $value
|
||||||
|
];
|
||||||
|
|
||||||
|
return new JSONResponse($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @param $type
|
||||||
|
* @return JSONResponse
|
||||||
|
*/
|
||||||
|
public function getUserValue($type) {
|
||||||
|
$status = self::STATE_OK;
|
||||||
|
$value ='nodata';
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case SettingsService::COLOR_FOR_NEW_NOTES_KEY:
|
||||||
|
$value = $this->settingsService->getColorForNewNotes($this->userId);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$status = self::STATE_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'status' => $status,
|
||||||
|
'value' => $value
|
||||||
|
];
|
||||||
|
|
||||||
|
return new JSONResponse($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
68
lib/Controller/ShareController.php
Normal file
68
lib/Controller/ShareController.php
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* @copyright 2020 Matias De lellis <mati86dl@gmail.com>
|
||||||
|
*
|
||||||
|
* @author 2020 Matias De lellis <mati86dl@gmail.com>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\QuickNotes\Controller;
|
||||||
|
|
||||||
|
use OCP\AppFramework\Http;
|
||||||
|
use OCP\AppFramework\Http\JSONResponse;
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
|
||||||
|
use OCP\IRequest;
|
||||||
|
|
||||||
|
use OCA\QuickNotes\Db\NoteShare;
|
||||||
|
use OCA\QuickNotes\Db\NoteShareMapper;
|
||||||
|
|
||||||
|
|
||||||
|
class ShareController extends Controller {
|
||||||
|
|
||||||
|
private $noteShareMapper;
|
||||||
|
private $userId;
|
||||||
|
|
||||||
|
public function __construct($AppName,
|
||||||
|
IRequest $request,
|
||||||
|
NoteShareMapper $noteShareMapper,
|
||||||
|
$userId)
|
||||||
|
{
|
||||||
|
parent::__construct($AppName, $request);
|
||||||
|
|
||||||
|
$this->noteShareMapper = $noteShareMapper;
|
||||||
|
$this->userId = $userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
*
|
||||||
|
* @param int $noteId
|
||||||
|
*/
|
||||||
|
public function destroy(int $noteId): JSONResponse {
|
||||||
|
try {
|
||||||
|
$noteShare = $this->noteShareMapper->findByNoteAndUser($noteId, $this->userId);
|
||||||
|
} catch (DoesNotExistException $e) {
|
||||||
|
return new JSONResponse([], Http::STATUS_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->noteShareMapper->delete($noteShare);
|
||||||
|
|
||||||
|
return new JSONResponse([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -73,8 +73,7 @@ class AttachMapper extends QBMapper {
|
|||||||
* @param string $userId
|
* @param string $userId
|
||||||
* @param int $noteId
|
* @param int $noteId
|
||||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
|
* @return Attach[]
|
||||||
* @return Note[]
|
|
||||||
*/
|
*/
|
||||||
public function findFromNote($userId, $noteId) {
|
public function findFromNote($userId, $noteId) {
|
||||||
$qb = $this->db->getQueryBuilder();
|
$qb = $this->db->getQueryBuilder();
|
||||||
@@ -86,4 +85,5 @@ class AttachMapper extends QBMapper {
|
|||||||
);
|
);
|
||||||
return $this->findEntities($qb);
|
return $this->findEntities($qb);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ class Note extends Entity implements JsonSerializable {
|
|||||||
protected $timestamp;
|
protected $timestamp;
|
||||||
protected $colorId;
|
protected $colorId;
|
||||||
protected $userId;
|
protected $userId;
|
||||||
protected $sharedWith;
|
protected $sharedWith = [];
|
||||||
|
protected $sharedBy = [];
|
||||||
protected $isShared;
|
protected $isShared;
|
||||||
protected $tags;
|
protected $tags;
|
||||||
protected $attachts;
|
protected $attachts;
|
||||||
@@ -40,8 +41,9 @@ class Note extends Entity implements JsonSerializable {
|
|||||||
'colorid' => $this->colorId,
|
'colorid' => $this->colorId,
|
||||||
'color' => $this->color,
|
'color' => $this->color,
|
||||||
'userid' => $this->userId,
|
'userid' => $this->userId,
|
||||||
'sharedwith' => $this->sharedWith,
|
'shared_with' => $this->sharedWith,
|
||||||
'isshared' => $this->isShared,
|
'shared_by' => $this->sharedBy,
|
||||||
|
'is_shared' => $this->isShared,
|
||||||
'tags' => $this->tags,
|
'tags' => $this->tags,
|
||||||
'attachts' => $this->attachts
|
'attachts' => $this->attachts
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -31,6 +31,22 @@ class NoteMapper extends QBMapper {
|
|||||||
return $this->findEntity($qb);
|
return $this->findEntity($qb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $id
|
||||||
|
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||||
|
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
|
||||||
|
* @return Note
|
||||||
|
*/
|
||||||
|
public function findShared($id) {
|
||||||
|
$qb = $this->db->getQueryBuilder();
|
||||||
|
$qb->select('*')
|
||||||
|
->from($this->tableName)
|
||||||
|
->where(
|
||||||
|
$qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))
|
||||||
|
);
|
||||||
|
return $this->findEntity($qb);
|
||||||
|
}
|
||||||
|
|
||||||
public function findAll($userId) {
|
public function findAll($userId) {
|
||||||
$qb = $this->db->getQueryBuilder();
|
$qb = $this->db->getQueryBuilder();
|
||||||
$qb->select('*')
|
$qb->select('*')
|
||||||
|
|||||||
@@ -8,15 +8,18 @@ use OCP\AppFramework\Db\Entity;
|
|||||||
class NoteShare extends Entity implements JsonSerializable {
|
class NoteShare extends Entity implements JsonSerializable {
|
||||||
|
|
||||||
protected $noteId;
|
protected $noteId;
|
||||||
|
protected $userId;
|
||||||
protected $sharedUser;
|
protected $sharedUser;
|
||||||
protected $sharedGroup;
|
protected $sharedGroup;
|
||||||
|
|
||||||
public function jsonSerialize() {
|
public function jsonSerialize() {
|
||||||
return [
|
return [
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
'noteid' => $this->noteId,
|
'user_id' => $this->userId,
|
||||||
'shareduser' => $this->sharedUser,
|
'note_id' => $this->noteId,
|
||||||
'sharedgroup' => $this->sharedGroup
|
'shared_user' => $this->sharedUser,
|
||||||
|
'shared_group' => $this->sharedGroup
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,4 +45,14 @@ class NoteShareMapper extends Mapper {
|
|||||||
$sql = 'DELETE FROM *PREFIX*quicknotes_shares WHERE note_id = ?';
|
$sql = 'DELETE FROM *PREFIX*quicknotes_shares WHERE note_id = ?';
|
||||||
$this->execute($sql, [$noteId]);
|
$this->execute($sql, [$noteId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function existsByNoteAndUser($noteId, $userId) {
|
||||||
|
$sql = 'SELECT * FROM *PREFIX*quicknotes_shares WHERE shared_user = ? AND note_id = ?';
|
||||||
|
try {
|
||||||
|
return $this->findEntities($sql, [$userId, $noteId]);
|
||||||
|
} catch (DoesNotExistException $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,13 +57,16 @@ class FileService {
|
|||||||
* @param int $fileId file id to show
|
* @param int $fileId file id to show
|
||||||
* @param int $sideSize side lenght to show
|
* @param int $sideSize side lenght to show
|
||||||
*/
|
*/
|
||||||
public function getPreviewUrl(int $fileId, int $sideSize): string {
|
public function getPreviewUrl(int $fileId, int $sideSize): ?string {
|
||||||
$userFolder = $this->rootFolder->getUserFolder($this->userId);
|
$userFolder = $this->rootFolder->getUserFolder($this->userId);
|
||||||
$node = current($userFolder->getById($fileId));
|
$file = current($userFolder->getById($fileId));
|
||||||
$path = $userFolder->getRelativePath($node->getPath());
|
|
||||||
|
if (!($file instanceof File)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreview', [
|
return $this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreview', [
|
||||||
'file' => $path,
|
'file' => $userFolder->getRelativePath($file->getPath()),
|
||||||
'x' => $sideSize,
|
'x' => $sideSize,
|
||||||
'y' => $sideSize
|
'y' => $sideSize
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -48,26 +48,29 @@ class NoteService {
|
|||||||
private $notemapper;
|
private $notemapper;
|
||||||
private $notetagmapper;
|
private $notetagmapper;
|
||||||
private $colormapper;
|
private $colormapper;
|
||||||
private $notesharemapper;
|
private $noteShareMapper;
|
||||||
private $attachMapper;
|
private $attachMapper;
|
||||||
private $tagmapper;
|
private $tagmapper;
|
||||||
private $fileService;
|
private $fileService;
|
||||||
|
private $settingsService;
|
||||||
|
|
||||||
public function __construct(NoteMapper $notemapper,
|
public function __construct(NoteMapper $notemapper,
|
||||||
NoteTagMapper $notetagmapper,
|
NoteTagMapper $notetagmapper,
|
||||||
NoteShareMapper $notesharemapper,
|
NoteShareMapper $noteShareMapper,
|
||||||
ColorMapper $colormapper,
|
ColorMapper $colormapper,
|
||||||
AttachMapper $attachMapper,
|
AttachMapper $attachMapper,
|
||||||
TagMapper $tagmapper,
|
TagMapper $tagmapper,
|
||||||
FileService $fileService)
|
FileService $fileService,
|
||||||
|
SettingsService $settingsService)
|
||||||
{
|
{
|
||||||
$this->notemapper = $notemapper;
|
$this->notemapper = $notemapper;
|
||||||
$this->notetagmapper = $notetagmapper;
|
$this->notetagmapper = $notetagmapper;
|
||||||
$this->colormapper = $colormapper;
|
$this->colormapper = $colormapper;
|
||||||
$this->notesharemapper = $notesharemapper;
|
$this->noteShareMapper = $noteShareMapper;
|
||||||
$this->attachMapper = $attachMapper;
|
$this->attachMapper = $attachMapper;
|
||||||
$this->tagmapper = $tagmapper;
|
$this->tagmapper = $tagmapper;
|
||||||
$this->fileService = $fileService;
|
$this->fileService = $fileService;
|
||||||
|
$this->settingsService = $settingsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,57 +78,62 @@ class NoteService {
|
|||||||
*/
|
*/
|
||||||
public function getAll(string $userId): array {
|
public function getAll(string $userId): array {
|
||||||
$notes = $this->notemapper->findAll($userId);
|
$notes = $this->notemapper->findAll($userId);
|
||||||
|
|
||||||
|
// Set shares with others.
|
||||||
foreach($notes as $note) {
|
foreach($notes as $note) {
|
||||||
$note->setIsShared(false);
|
$note->setIsShared(false);
|
||||||
$sharedWith = $this->notesharemapper->getSharesForNote($note->getId());
|
$note->setSharedWith($this->noteShareMapper->getSharesForNote($note->getId()));
|
||||||
if(count($sharedWith) > 0) {
|
|
||||||
$shareList = array();
|
|
||||||
foreach($sharedWith as $share) {
|
|
||||||
$shareList[] = $share->getSharedUser();
|
|
||||||
}
|
|
||||||
$note->setSharedWith(implode(", ", $shareList));
|
|
||||||
} else {
|
|
||||||
$note->setSharedWith(null);
|
|
||||||
}
|
|
||||||
$note->setTags($this->tagmapper->getTagsForNote($userId, $note->getId()));
|
|
||||||
}
|
|
||||||
$shareEntries = $this->notesharemapper->findForUser($userId);
|
|
||||||
$shares = array();
|
|
||||||
foreach($shareEntries as $entry) {
|
|
||||||
try {
|
|
||||||
//find is only to check if current user is owner
|
|
||||||
$this->notemapper->find($entry->getNoteId(), $userId);
|
|
||||||
//user is owner, nothing to do
|
|
||||||
} catch(\OCP\AppFramework\Db\DoesNotExistException $e) {
|
|
||||||
$share = $this->notemapper->findById($entry->getNoteId());
|
|
||||||
$share->setIsShared(true);
|
|
||||||
$shares[] = $share;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get shares from others.
|
||||||
|
$shares = [];
|
||||||
|
$sharedEntries = $this->noteShareMapper->findForUser($userId);
|
||||||
|
foreach($sharedEntries as $sharedEntry) {
|
||||||
|
$sharedNote = $this->notemapper->findShared($sharedEntry->getNoteId());
|
||||||
|
$sharedNote->setIsShared(true);
|
||||||
|
|
||||||
|
$sharedEntry->setUserId($sharedNote->getUserId());
|
||||||
|
$sharedNote->setSharedBy([$sharedEntry]);
|
||||||
|
$shares[] = $sharedNote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attahch shared notes from others to same response
|
||||||
$notes = array_merge($notes, $shares);
|
$notes = array_merge($notes, $shares);
|
||||||
|
|
||||||
|
// Set tags to response.
|
||||||
foreach($notes as $note) {
|
foreach($notes as $note) {
|
||||||
$note->setTitle(strip_tags($note->getTitle()));
|
$note->setTags($this->tagmapper->getTagsForNote($userId, $note->getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert true color to response
|
// Insert color to response
|
||||||
foreach ($notes as $note) {
|
foreach ($notes as $note) {
|
||||||
$note->setColor($this->colormapper->find($note->getColorId())->getColor());
|
$note->setColor($this->colormapper->find($note->getColorId())->getColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert true color to response
|
// Insert pin to response
|
||||||
foreach ($notes as $note) {
|
foreach ($notes as $note) {
|
||||||
$note->setIsPinned($note->getPinned() ? true : false);
|
$note->setIsPinned($note->getPinned() ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert true attachts to response
|
// Insert attachts to response.
|
||||||
foreach ($notes as $note) {
|
foreach ($notes as $note) {
|
||||||
$attachts = $this->attachMapper->findFromNote($userId, $note->getId());
|
$rAttachts = [];
|
||||||
|
$attachts = $this->attachMapper->findFromNote($note->getUserId(), $note->getId());
|
||||||
foreach ($attachts as $attach) {
|
foreach ($attachts as $attach) {
|
||||||
$attach->setPreviewUrl($this->fileService->getPreviewUrl($attach->getFileId(), 512));
|
$previewUrl = $this->fileService->getPreviewUrl($attach->getFileId(), 512);
|
||||||
$attach->setRedirectUrl($this->fileService->getRedirectToFileUrl($attach->getFileId()));
|
if (is_null($previewUrl))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$redirectUrl = $this->fileService->getRedirectToFileUrl($attach->getFileId());
|
||||||
|
if (is_null($redirectUrl))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$attach->setPreviewUrl($previewUrl);
|
||||||
|
$attach->setRedirectUrl($redirectUrl);
|
||||||
|
|
||||||
|
$rAttachts[] = $attach;
|
||||||
}
|
}
|
||||||
$note->setAttachts($attachts);
|
$note->setAttachts($rAttachts);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $notes;
|
return $notes;
|
||||||
@@ -149,7 +157,11 @@ class NoteService {
|
|||||||
* @param string $content
|
* @param string $content
|
||||||
* @param string $color
|
* @param string $color
|
||||||
*/
|
*/
|
||||||
public function create(string $userId, string $title, string $content, string $color = "#F7EB96"): Note {
|
public function create(string $userId, string $title, string $content, string $color = NULL): Note {
|
||||||
|
if (is_null($color)) {
|
||||||
|
$color = $this->settingsService->getColorForNewNotes();
|
||||||
|
}
|
||||||
|
|
||||||
// Get color or append it
|
// Get color or append it
|
||||||
if ($this->colormapper->colorExists($color)) {
|
if ($this->colormapper->colorExists($color)) {
|
||||||
$hcolor = $this->colormapper->findByColor($color);
|
$hcolor = $this->colormapper->findByColor($color);
|
||||||
@@ -187,6 +199,7 @@ class NoteService {
|
|||||||
* @param array $attachts
|
* @param array $attachts
|
||||||
* @param bool $pinned
|
* @param bool $pinned
|
||||||
* @param array $tags
|
* @param array $tags
|
||||||
|
* @param array $shares
|
||||||
* @param string $color
|
* @param string $color
|
||||||
*/
|
*/
|
||||||
public function update(string $userId,
|
public function update(string $userId,
|
||||||
@@ -196,14 +209,14 @@ class NoteService {
|
|||||||
array $attachts,
|
array $attachts,
|
||||||
bool $pinned,
|
bool $pinned,
|
||||||
array $tags,
|
array $tags,
|
||||||
string $color): Note
|
array $shares,
|
||||||
|
string $color): ?Note
|
||||||
{
|
{
|
||||||
// Get current Note and Color.
|
// Get current Note and Color.
|
||||||
try {
|
$note = $this->get($userId, $id);
|
||||||
$note = $this->notemapper->find($id, $userId);
|
if (is_null($note))
|
||||||
} catch(Exception $e) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
$oldcolorid = $note->getColorId();
|
$oldcolorid = $note->getColorId();
|
||||||
|
|
||||||
// Get new Color or append it.
|
// Get new Color or append it.
|
||||||
@@ -242,6 +255,31 @@ class NoteService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete old shares
|
||||||
|
$dbShares = $this->noteShareMapper->getSharesForNote($id);
|
||||||
|
foreach ($dbShares as $dbShare) {
|
||||||
|
$delete = true;
|
||||||
|
foreach ($shares as $share) {
|
||||||
|
if ($dbShare->getSharedUser() === $share['name']) {
|
||||||
|
$delete = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($delete) {
|
||||||
|
$this->noteShareMapper->delete($dbShare);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new shares
|
||||||
|
foreach ($shares as $share) {
|
||||||
|
if (!$this->noteShareMapper->existsByNoteAndUser($id, $share['name'])) {
|
||||||
|
$hShare = new NoteShare();
|
||||||
|
$hShare->setNoteId($id);
|
||||||
|
$hShare->setSharedUser($share['name']);
|
||||||
|
$this->noteShareMapper->insert($hShare);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Delete old tag relations
|
// Delete old tag relations
|
||||||
$dbTags = $this->tagmapper->getTagsForNote($userId, $id);
|
$dbTags = $this->tagmapper->getTagsForNote($userId, $id);
|
||||||
foreach ($dbTags as $dbTag) {
|
foreach ($dbTags as $dbTag) {
|
||||||
@@ -304,6 +342,10 @@ class NoteService {
|
|||||||
}
|
}
|
||||||
$newnote->setAttachts($attachts);
|
$newnote->setAttachts($attachts);
|
||||||
|
|
||||||
|
// Fill shared with with others
|
||||||
|
$newnote->setIsShared(false);
|
||||||
|
$newnote->setSharedWith($this->noteShareMapper->getSharesForNote($newnote->getId()));
|
||||||
|
|
||||||
// Remove old color if necessary
|
// Remove old color if necessary
|
||||||
if (($oldcolorid !== $hcolor->getId()) &&
|
if (($oldcolorid !== $hcolor->getId()) &&
|
||||||
(!$this->notemapper->colorIdCount($oldcolorid))) {
|
(!$this->notemapper->colorIdCount($oldcolorid))) {
|
||||||
@@ -330,7 +372,7 @@ class NoteService {
|
|||||||
}
|
}
|
||||||
$oldcolorid = $note->getColorId();
|
$oldcolorid = $note->getColorId();
|
||||||
|
|
||||||
$this->notesharemapper->deleteByNoteId($note->getId());
|
$this->noteShareMapper->deleteByNoteId($note->getId());
|
||||||
|
|
||||||
// Delete note.
|
// Delete note.
|
||||||
$this->notemapper->delete($note);
|
$this->notemapper->delete($note);
|
||||||
@@ -381,7 +423,7 @@ class NoteService {
|
|||||||
}
|
}
|
||||||
$pos_users = array();
|
$pos_users = array();
|
||||||
$pos_groups = array();
|
$pos_groups = array();
|
||||||
$shares = $this->notesharemapper->getSharesForNote($noteId);
|
$shares = $this->noteShareMapper->getSharesForNote($noteId);
|
||||||
foreach($shares as $s) {
|
foreach($shares as $s) {
|
||||||
$shareType = $s->getSharedUser();
|
$shareType = $s->getSharedUser();
|
||||||
if(strlen($shareType) !== 0) {
|
if(strlen($shareType) !== 0) {
|
||||||
@@ -406,14 +448,14 @@ class NoteService {
|
|||||||
$share = new NoteShare();
|
$share = new NoteShare();
|
||||||
$share->setSharedGroup($groupId);
|
$share->setSharedGroup($groupId);
|
||||||
$share->setNoteId($noteId);
|
$share->setNoteId($noteId);
|
||||||
$this->notesharemapper->insert($share);
|
$this->noteShareMapper->insert($share);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public function removeGroupShare($groupId, $noteId) {
|
public function removeGroupShare($groupId, $noteId) {
|
||||||
$share = $this->notesharemapper->findByNoteAndGroup($noteId, $groupId);
|
$share = $this->noteShareMapper->findByNoteAndGroup($noteId, $groupId);
|
||||||
$this->notesharemapper->delete($share);
|
$this->noteShareMapper->delete($share);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -422,13 +464,13 @@ class NoteService {
|
|||||||
$share = new NoteShare();
|
$share = new NoteShare();
|
||||||
$share->setSharedUser($userId);
|
$share->setSharedUser($userId);
|
||||||
$share->setNoteId($noteId);
|
$share->setNoteId($noteId);
|
||||||
$this->notesharemapper->insert($share);
|
$this->noteShareMapper->insert($share);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public function removeUserShare($userId, $noteId) {
|
public function removeUserShare($userId, $noteId) {
|
||||||
$share = $this->notesharemapper->findByNoteAndUser($noteId, $userId);
|
$share = $this->noteShareMapper->findByNoteAndUser($noteId, $userId);
|
||||||
$this->notesharemapper->delete($share);
|
$this->noteShareMapper->delete($share);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
65
lib/Service/SettingsService.php
Normal file
65
lib/Service/SettingsService.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2020 Matias De lellis <mati86dl@gmail.com>
|
||||||
|
*
|
||||||
|
* @author Matias De lellis <mati86dl@gmail.com>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\QuickNotes\Service;
|
||||||
|
|
||||||
|
use OCA\QuickNotes\AppInfo\Application;
|
||||||
|
|
||||||
|
use OCP\IConfig;
|
||||||
|
|
||||||
|
class SettingsService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings keys and default values.
|
||||||
|
*/
|
||||||
|
const COLOR_FOR_NEW_NOTES_KEY = 'default_color';
|
||||||
|
const DEFAULT_COLOR_FOR_NEW_NOTES = '#F7EB96';
|
||||||
|
|
||||||
|
/** @var IConfig Config */
|
||||||
|
private $config;
|
||||||
|
|
||||||
|
/** @var string|null */
|
||||||
|
private $userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IConfig $config
|
||||||
|
* @param string $userId
|
||||||
|
*/
|
||||||
|
public function __construct(IConfig $config,
|
||||||
|
$userId)
|
||||||
|
{
|
||||||
|
$this->config = $config;
|
||||||
|
$this->userId = $userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getColorForNewNotes(): string {
|
||||||
|
return $this->config->getUserValue($this->userId, Application::APP_NAME, self::COLOR_FOR_NEW_NOTES_KEY, self::DEFAULT_COLOR_FOR_NEW_NOTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setColorForNewNotes(string $color) {
|
||||||
|
$this->config->setUserValue($this->userId, Application::APP_NAME, self::COLOR_FOR_NEW_NOTES_KEY, $color);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,3 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
p($l->t('Delete attachment'));
|
p($l->t('Delete attachment'));
|
||||||
p($l->t('Attach file'));
|
p($l->t('Attach file'));
|
||||||
|
p($l->t('Shared'));
|
||||||
|
p($l->t('Shared with others'));
|
||||||
|
p($l->t('Shared with you'));
|
||||||
|
p($l->t('Share note'));
|
||||||
|
p($l->t('Close'));
|
||||||
|
p($l->t('Default color for new notes'));
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<div id="app-settings">
|
<div id="app-settings">
|
||||||
<div id="app-settings-header">
|
<div id="app-settings-header">
|
||||||
<button class="settings-button"
|
<button class="settings-button" data-apps-slide-toggle="#app-settings-content">
|
||||||
data-apps-slide-toggle="#app-settings-content"
|
<?php p($l->t('Settings'));?>
|
||||||
></button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="app-settings-content">
|
<div id="app-settings-content">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user