mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 13:39:01 +01:00 
			
		
		
		
	all access to notes and branches is now async so we can lazy load it in the future
This commit is contained in:
		
							parent
							
								
									297a2cd9da
								
							
						
					
					
						commit
						54e4f54678
					
				@ -1,4 +1,5 @@
 | 
			
		||||
import treeService from '../services/tree.js';
 | 
			
		||||
import server from '../services/server.js';
 | 
			
		||||
 | 
			
		||||
const $dialog = $("#edit-tree-prefix-dialog");
 | 
			
		||||
const $form = $("#edit-tree-prefix-form");
 | 
			
		||||
@ -18,9 +19,9 @@ async function showDialog() {
 | 
			
		||||
    const currentNode = treeService.getCurrentNode();
 | 
			
		||||
 | 
			
		||||
    branchId = currentNode.data.branchId;
 | 
			
		||||
    const nt = treeService.getBranch(branchId);
 | 
			
		||||
    const branch = await treeService.getBranch(branchId);
 | 
			
		||||
 | 
			
		||||
    $treePrefixInput.val(nt.prefix).focus();
 | 
			
		||||
    $treePrefixInput.val(branch.prefix).focus();
 | 
			
		||||
 | 
			
		||||
    const noteTitle = treeService.getNoteTitle(currentNode.data.noteId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
import linkService from '../services/link.js';
 | 
			
		||||
import utils from '../services/utils.js';
 | 
			
		||||
import server from '../services/server.js';
 | 
			
		||||
 | 
			
		||||
const $dialog = $("#event-log-dialog");
 | 
			
		||||
const $list = $("#event-log-list");
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
import noteDetailService from '../services/note_detail.js';
 | 
			
		||||
import utils from '../services/utils.js';
 | 
			
		||||
import server from '../services/server.js';
 | 
			
		||||
 | 
			
		||||
const $showDialogButton = $(".show-labels-button");
 | 
			
		||||
const $dialog = $("#labels-dialog");
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
import noteDetailService from '../services/note_detail.js';
 | 
			
		||||
import utils from '../services/utils.js';
 | 
			
		||||
import server from '../services/server.js';
 | 
			
		||||
 | 
			
		||||
const $showDialogButton = $("#show-history-button");
 | 
			
		||||
const $dialog = $("#note-history-dialog");
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
import linkService from '../services/link.js';
 | 
			
		||||
import utils from '../services/utils.js';
 | 
			
		||||
import server from '../services/server.js';
 | 
			
		||||
 | 
			
		||||
const $showDialogButton = $("#recent-changes-button");
 | 
			
		||||
const $dialog = $("#recent-changes-dialog");
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@ function addRecentNote(branchId, notePath) {
 | 
			
		||||
    }, 1500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showDialog() {
 | 
			
		||||
async function showDialog() {
 | 
			
		||||
    glob.activeDialog = $dialog;
 | 
			
		||||
 | 
			
		||||
    $dialog.dialog({
 | 
			
		||||
@ -40,25 +40,28 @@ function showDialog() {
 | 
			
		||||
 | 
			
		||||
    // remove the current note
 | 
			
		||||
    const recNotes = list.filter(note => note !== treeService.getCurrentNotePath());
 | 
			
		||||
    const items = [];
 | 
			
		||||
 | 
			
		||||
    for (const notePath of recNotes) {
 | 
			
		||||
        let noteTitle;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            noteTitle = await treeService.getNotePathTitle(notePath);
 | 
			
		||||
        }
 | 
			
		||||
        catch (e) {
 | 
			
		||||
            noteTitle = "[error - can't find note title]";
 | 
			
		||||
 | 
			
		||||
            messagingService.logError("Could not find title for notePath=" + notePath + ", stack=" + e.stack);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        items.push({
 | 
			
		||||
            label: noteTitle,
 | 
			
		||||
            value: notePath
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $searchInput.autocomplete({
 | 
			
		||||
        source: recNotes.map(notePath => {
 | 
			
		||||
            let noteTitle;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                noteTitle = treeService.getNotePathTitle(notePath);
 | 
			
		||||
            }
 | 
			
		||||
            catch (e) {
 | 
			
		||||
                noteTitle = "[error - can't find note title]";
 | 
			
		||||
 | 
			
		||||
                messagingService.logError("Could not find title for notePath=" + notePath + ", stack=" + e.stack);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                label: noteTitle,
 | 
			
		||||
                value: notePath
 | 
			
		||||
            }
 | 
			
		||||
        }),
 | 
			
		||||
        source: items,
 | 
			
		||||
        minLength: 0,
 | 
			
		||||
        autoFocus: true,
 | 
			
		||||
        select: function (event, ui) {
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import utils from '../services/utils.js';
 | 
			
		||||
import server from '../services/server.js';
 | 
			
		||||
 | 
			
		||||
const $dialog = $("#sql-console-dialog");
 | 
			
		||||
const $query = $('#sql-console-query');
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@ class Branch {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async getNote() {
 | 
			
		||||
        return this.treeCache.getNote(this.noteId);
 | 
			
		||||
        return await this.treeCache.getNote(this.noteId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get toString() {
 | 
			
		||||
 | 
			
		||||
@ -99,11 +99,11 @@ const contextMenuSettings = {
 | 
			
		||||
        {title: "Sort alphabetically <kbd>Alt+S</kbd>", cmd: "sortAlphabetically", uiIcon: " ui-icon-arrowthick-2-n-s"}
 | 
			
		||||
 | 
			
		||||
    ],
 | 
			
		||||
    beforeOpen: (event, ui) => {
 | 
			
		||||
    beforeOpen: async (event, ui) => {
 | 
			
		||||
        const node = $.ui.fancytree.getNode(ui.target);
 | 
			
		||||
        const branch = treeService.getBranch(node.data.branchId);
 | 
			
		||||
        const note = treeService.getNote(node.data.noteId);
 | 
			
		||||
        const parentNote = treeService.getNote(branch.parentNoteId);
 | 
			
		||||
        const branch = await treeService.getBranch(node.data.branchId);
 | 
			
		||||
        const note = await treeService.getNote(node.data.noteId);
 | 
			
		||||
        const parentNote = await treeService.getNote(branch.parentNoteId);
 | 
			
		||||
 | 
			
		||||
        // Modify menu entries depending on node status
 | 
			
		||||
        $tree.contextmenu("enableEntry", "pasteAfter", clipboardIds.length > 0 && (!parentNote || parentNote.type !== 'search'));
 | 
			
		||||
 | 
			
		||||
@ -22,23 +22,23 @@ let instanceName = null; // should have better place
 | 
			
		||||
 | 
			
		||||
let startNotePath = null;
 | 
			
		||||
 | 
			
		||||
function getNote(noteId) {
 | 
			
		||||
    const note = treeCache.getNote(noteId);
 | 
			
		||||
async function getNote(noteId) {
 | 
			
		||||
    const note = await treeCache.getNote(noteId);
 | 
			
		||||
 | 
			
		||||
    if (!note) {
 | 
			
		||||
        utils.throwError("Can't find title for noteId='" + noteId + "'");
 | 
			
		||||
        utils.throwError(`Can't find title for noteId='${noteId}'`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return note;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getNoteTitle(noteId, parentNoteId = null) {
 | 
			
		||||
async function getNoteTitle(noteId, parentNoteId = null) {
 | 
			
		||||
    utils.assertArguments(noteId);
 | 
			
		||||
 | 
			
		||||
    let title = treeCache.getNote(noteId).title;
 | 
			
		||||
    let {title} = await treeCache.getNote(noteId);
 | 
			
		||||
 | 
			
		||||
    if (parentNoteId !== null) {
 | 
			
		||||
        const branch = treeCache.getBranchByChildParent(noteId, parentNoteId);
 | 
			
		||||
        const branch = await treeCache.getBranchByChildParent(noteId, parentNoteId);
 | 
			
		||||
 | 
			
		||||
        if (branch && branch.prefix) {
 | 
			
		||||
            title = branch.prefix + ' - ' + title;
 | 
			
		||||
@ -59,10 +59,10 @@ function getCurrentNotePath() {
 | 
			
		||||
    return treeUtils.getNotePath(node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getNodesByBranchId(branchId) {
 | 
			
		||||
async function getNodesByBranchId(branchId) {
 | 
			
		||||
    utils.assertArguments(branchId);
 | 
			
		||||
 | 
			
		||||
    const branch = treeCache.getBranch(branchId);
 | 
			
		||||
    const branch = await treeCache.getBranch(branchId);
 | 
			
		||||
 | 
			
		||||
    return getNodesByNoteId(branch.noteId).filter(node => node.data.branchId === branchId);
 | 
			
		||||
}
 | 
			
		||||
@ -74,17 +74,21 @@ function getNodesByNoteId(noteId) {
 | 
			
		||||
    return list ? list : []; // if no nodes with this refKey are found, fancy tree returns null
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setPrefix(branchId, prefix) {
 | 
			
		||||
async function setPrefix(branchId, prefix) {
 | 
			
		||||
    utils.assertArguments(branchId);
 | 
			
		||||
 | 
			
		||||
    treeCache.getBranch(branchId).prefix = prefix;
 | 
			
		||||
    const branch = await treeCache.getBranch(branchId);
 | 
			
		||||
 | 
			
		||||
    getNodesByBranchId(branchId).map(node => setNodeTitleWithPrefix(node));
 | 
			
		||||
    branch.prefix = prefix;
 | 
			
		||||
 | 
			
		||||
    for (const node of await getNodesByBranchId(branchId)) {
 | 
			
		||||
        await setNodeTitleWithPrefix(node);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setNodeTitleWithPrefix(node) {
 | 
			
		||||
    const noteTitle = getNoteTitle(node.data.noteId);
 | 
			
		||||
    const branch = treeCache.getBranch(node.data.branchId);
 | 
			
		||||
async function setNodeTitleWithPrefix(node) {
 | 
			
		||||
    const noteTitle = await getNoteTitle(node.data.noteId);
 | 
			
		||||
    const branch = await treeCache.getBranch(node.data.branchId);
 | 
			
		||||
 | 
			
		||||
    const prefix = branch.prefix;
 | 
			
		||||
 | 
			
		||||
@ -102,14 +106,14 @@ function removeParentChildRelation(parentNoteId, childNoteId) {
 | 
			
		||||
    delete treeCache.childParentToBranch[childNoteId + '-' + parentNoteId];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setParentChildRelation(branchId, parentNoteId, childNoteId) {
 | 
			
		||||
async function setParentChildRelation(branchId, parentNoteId, childNoteId) {
 | 
			
		||||
    treeCache.parents[childNoteId] = treeCache.parents[childNoteId] || [];
 | 
			
		||||
    treeCache.parents[childNoteId].push(treeCache.getNote(parentNoteId));
 | 
			
		||||
    treeCache.parents[childNoteId].push(await treeCache.getNote(parentNoteId));
 | 
			
		||||
 | 
			
		||||
    treeCache.children[parentNoteId] = treeCache.children[parentNoteId] || [];
 | 
			
		||||
    treeCache.children[parentNoteId].push(treeCache.getNote(childNoteId));
 | 
			
		||||
    treeCache.children[parentNoteId].push(await treeCache.getNote(childNoteId));
 | 
			
		||||
 | 
			
		||||
    treeCache.childParentToBranch[childNoteId + '-' + parentNoteId] = treeCache.getBranch(branchId);
 | 
			
		||||
    treeCache.childParentToBranch[childNoteId + '-' + parentNoteId] = await treeCache.getBranch(branchId);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function prepareBranch(noteRows, branchRows) {
 | 
			
		||||
@ -117,7 +121,7 @@ async function prepareBranch(noteRows, branchRows) {
 | 
			
		||||
 | 
			
		||||
    treeCache.load(noteRows, branchRows);
 | 
			
		||||
 | 
			
		||||
    return await prepareBranchInner(treeCache.getNote('root'));
 | 
			
		||||
    return await prepareBranchInner(await treeCache.getNote('root'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function getExtraClasses(note) {
 | 
			
		||||
@ -239,7 +243,7 @@ async function getRunPath(notePath) {
 | 
			
		||||
        const parentNoteId = path[i++];
 | 
			
		||||
 | 
			
		||||
        if (childNoteId !== null) {
 | 
			
		||||
            const child = treeCache.getNote(childNoteId);
 | 
			
		||||
            const child = await treeCache.getNote(childNoteId);
 | 
			
		||||
            const parents = await child.getParentNotes();
 | 
			
		||||
 | 
			
		||||
            if (!parents) {
 | 
			
		||||
@ -287,7 +291,7 @@ async function getRunPath(notePath) {
 | 
			
		||||
async function showParentList(noteId, node) {
 | 
			
		||||
    utils.assertArguments(noteId, node);
 | 
			
		||||
 | 
			
		||||
    const note = treeCache.getNote(noteId);
 | 
			
		||||
    const note = await treeCache.getNote(noteId);
 | 
			
		||||
    const parents = await note.getParentNotes();
 | 
			
		||||
 | 
			
		||||
    if (!parents.length) {
 | 
			
		||||
@ -305,7 +309,7 @@ async function showParentList(noteId, node) {
 | 
			
		||||
            const parentNotePath = await getSomeNotePath(parentNote);
 | 
			
		||||
            // this is to avoid having root notes leading '/'
 | 
			
		||||
            const notePath = parentNotePath ? (parentNotePath + '/' + noteId) : noteId;
 | 
			
		||||
            const title = getNotePathTitle(notePath);
 | 
			
		||||
            const title = await getNotePathTitle(notePath);
 | 
			
		||||
 | 
			
		||||
            let item;
 | 
			
		||||
 | 
			
		||||
@ -321,7 +325,7 @@ async function showParentList(noteId, node) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getNotePathTitle(notePath) {
 | 
			
		||||
async function getNotePathTitle(notePath) {
 | 
			
		||||
    utils.assertArguments(notePath);
 | 
			
		||||
 | 
			
		||||
    const titlePath = [];
 | 
			
		||||
@ -329,7 +333,7 @@ function getNotePathTitle(notePath) {
 | 
			
		||||
    let parentNoteId = 'root';
 | 
			
		||||
 | 
			
		||||
    for (const noteId of notePath.split('/')) {
 | 
			
		||||
        titlePath.push(getNoteTitle(noteId, parentNoteId));
 | 
			
		||||
        titlePath.push(await getNoteTitle(noteId, parentNoteId));
 | 
			
		||||
 | 
			
		||||
        parentNoteId = noteId;
 | 
			
		||||
    }
 | 
			
		||||
@ -394,6 +398,23 @@ function clearSelectedNodes() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function treeInitialized() {
 | 
			
		||||
    const noteId = treeUtils.getNoteIdFromNotePath(startNotePath);
 | 
			
		||||
 | 
			
		||||
    if ((await treeCache.getNote(noteId)) === undefined) {
 | 
			
		||||
        // note doesn't exist so don't try to activate it
 | 
			
		||||
        startNotePath = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (startNotePath) {
 | 
			
		||||
        activateNode(startNotePath);
 | 
			
		||||
 | 
			
		||||
        // looks like this this doesn't work when triggered immediatelly after activating node
 | 
			
		||||
        // so waiting a second helps
 | 
			
		||||
        setTimeout(scrollToCurrentNote, 1000);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function initFancyTree(branch) {
 | 
			
		||||
    utils.assertArguments(branch);
 | 
			
		||||
 | 
			
		||||
@ -566,20 +587,7 @@ function initFancyTree(branch) {
 | 
			
		||||
            setExpandedToServer(data.node.data.branchId, false);
 | 
			
		||||
        },
 | 
			
		||||
        init: (event, data) => {
 | 
			
		||||
            const noteId = treeUtils.getNoteIdFromNotePath(startNotePath);
 | 
			
		||||
 | 
			
		||||
            if (treeCache.getNote(noteId) === undefined) {
 | 
			
		||||
                // note doesn't exist so don't try to activate it
 | 
			
		||||
                startNotePath = null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (startNotePath) {
 | 
			
		||||
                activateNode(startNotePath);
 | 
			
		||||
 | 
			
		||||
                // looks like this this doesn't work when triggered immediatelly after activating node
 | 
			
		||||
                // so waiting a second helps
 | 
			
		||||
                setTimeout(scrollToCurrentNote, 1000);
 | 
			
		||||
            }
 | 
			
		||||
            treeInitialized();
 | 
			
		||||
        },
 | 
			
		||||
        hotkeys: {
 | 
			
		||||
            keydown: keybindings
 | 
			
		||||
@ -597,9 +605,9 @@ function initFancyTree(branch) {
 | 
			
		||||
            mode: "hide"       // Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
 | 
			
		||||
        },
 | 
			
		||||
        dnd: dragAndDropSetup,
 | 
			
		||||
        lazyLoad: function(event, data){
 | 
			
		||||
        lazyLoad: async function(event, data){
 | 
			
		||||
            const noteId = data.node.data.noteId;
 | 
			
		||||
            const note = getNote(noteId);
 | 
			
		||||
            const note = await getNote(noteId);
 | 
			
		||||
 | 
			
		||||
            if (note.type === 'search') {
 | 
			
		||||
                data.result = loadSearchNote(noteId);
 | 
			
		||||
@ -635,7 +643,7 @@ async function loadSearchNote(searchNoteId) {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return await prepareBranchInner(treeCache.getNote(searchNoteId));
 | 
			
		||||
    return await prepareBranchInner(await treeCache.getNote(searchNoteId));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getTree() {
 | 
			
		||||
@ -704,7 +712,7 @@ async function getAutocompleteItems(parentNoteId, notePath, titlePath) {
 | 
			
		||||
        parentNoteId = 'root';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const parentNote = treeCache.getNote(parentNoteId);
 | 
			
		||||
    const parentNote = await treeCache.getNote(parentNoteId);
 | 
			
		||||
    const childNotes = await parentNote.getChildNotes();
 | 
			
		||||
 | 
			
		||||
    if (!childNotes.length) {
 | 
			
		||||
@ -730,7 +738,7 @@ async function getAutocompleteItems(parentNoteId, notePath, titlePath) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const childNotePath = (notePath ? (notePath + '/') : '') + childNote.noteId;
 | 
			
		||||
        const childTitlePath = (titlePath ? (titlePath + ' / ') : '') + getNoteTitle(childNote.noteId, parentNoteId);
 | 
			
		||||
        const childTitlePath = (titlePath ? (titlePath + ' / ') : '') + await getNoteTitle(childNote.noteId, parentNoteId);
 | 
			
		||||
 | 
			
		||||
        autocompleteItems.push({
 | 
			
		||||
            value: childTitlePath + ' (' + childNotePath + ')',
 | 
			
		||||
@ -747,12 +755,14 @@ async function getAutocompleteItems(parentNoteId, notePath, titlePath) {
 | 
			
		||||
    return autocompleteItems;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function setNoteTitle(noteId, title) {
 | 
			
		||||
async function setNoteTitle(noteId, title) {
 | 
			
		||||
    utils.assertArguments(noteId);
 | 
			
		||||
 | 
			
		||||
    getNote(noteId).title = title;
 | 
			
		||||
 | 
			
		||||
    getNodesByNoteId(noteId).map(clone => setNodeTitleWithPrefix(clone));
 | 
			
		||||
    for (const clone of getNodesByNoteId(noteId)) {
 | 
			
		||||
        await setNodeTitleWithPrefix(clone);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function createNewTopLevelNote() {
 | 
			
		||||
@ -835,15 +845,15 @@ async function sortAlphabetically(noteId) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function noteExists(noteId) {
 | 
			
		||||
    return !!treeCache.getNote(noteId);
 | 
			
		||||
    return !!(await treeCache.getNote(noteId));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getInstanceName() {
 | 
			
		||||
    return instanceName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getBranch(branchId) {
 | 
			
		||||
    return branchMap[branchId];
 | 
			
		||||
async function getBranch(branchId) {
 | 
			
		||||
    return await treeCache.getBranch(branchId);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$(document).bind('keydown', 'ctrl+o', e => {
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,8 @@ class TreeCache {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getNote(noteId) {
 | 
			
		||||
    /** @return NoteShort */
 | 
			
		||||
    async getNote(noteId) {
 | 
			
		||||
        return this.notes[noteId];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -47,11 +48,13 @@ class TreeCache {
 | 
			
		||||
        this.addBranch(branch);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getBranch(branchId) {
 | 
			
		||||
    /** @return Branch */
 | 
			
		||||
    async getBranch(branchId) {
 | 
			
		||||
        return this.branches[branchId];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getBranchByChildParent(childNoteId, parentNoteId) {
 | 
			
		||||
    /** @return Branch */
 | 
			
		||||
    async getBranchByChildParent(childNoteId, parentNoteId) {
 | 
			
		||||
        const key = (childNoteId + '-' + parentNoteId);
 | 
			
		||||
        const branch = this.childParentToBranch[key];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user