Skip to content

Commit

Permalink
#204 - global search
Browse files Browse the repository at this point in the history
  • Loading branch information
viliusle committed Jun 21, 2021
1 parent b7a8e5e commit fa6d7b6
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 4 deletions.
7 changes: 6 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"blueimp-canvas-to-blob": "^3.28.0",
"exif-js": "^2.3.0",
"file-saver": "^2.0.5",
"fuzzysort": "^1.1.4",
"gif.js.optimized": "^1.0.1",
"hermite-resize": "git+https://github.com/viliusle/Hermite-resize.git",
"jquery": "^3.5.1",
Expand Down
21 changes: 21 additions & 0 deletions src/css/component.css
Original file line number Diff line number Diff line change
Expand Up @@ -709,3 +709,24 @@ button img{
background-color: var(--background-color-active);
color: var(--text-color-active);
}

/* global search */
#global_search_results{
padding-top: 10px;
font-size: 14px;
}
#global_search_results .search-result {
padding: 3px 5px;
}
#global_search_results .search-result.active{
background-color: var(--background-color-active);
color: var(--text-color-active);
border-radius: 2px;
}
#global_search_results b{
color: var(--text-color-red);
}

.popup.shortcuts table{
line-height: 1;
}
6 changes: 6 additions & 0 deletions src/js/config-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,12 @@ const menuDefinition = [
}
]
},
{
name: 'Search',
shortcut: 'F3',
ellipsis: true,
target: 'tools/search.search'
},
{
name: 'Settings',
ellipsis: true,
Expand Down
166 changes: 166 additions & 0 deletions src/js/core/base-search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* miniPaint - https://github.com/viliusle/miniPaint
* author: Vilius L.
*/

import config from './../config.js';
import Dialog_class from './../libs/popup.js';
import Base_gui_class from './base-gui.js';
const fuzzysort = require('fuzzysort');

var instance = null;

class Base_search_class {

constructor() {
//singleton
if (instance) {
return instance;
}
instance = this;

this.POP = new Dialog_class();
this.Base_gui = new Base_gui_class();
this.db = null;

this.events();
}

events() {
document.addEventListener('keydown', (event) => {
if (this.POP.get_active_instances() > 0) {
return;
}

var code = event.key.toLowerCase();
if (code == "f3") {
//open
this.search();
event.preventDefault();
}
}, false);

document.addEventListener('input', (event) => {
if(document.querySelector('#pop_data_search') == null){
return;
}

var node = document.querySelector('#global_search_results');
node.innerHTML = '';

var query = event.target.value;
if(query == ''){
return;
}

let results = fuzzysort.go(query, this.db, {
keys: ['title'],
limit: 10,
threshold: -50000,
});

//show
for(var i = 0; i < results.length; i++) {
var item = results[i];

var className = "search-result n" + (i+1);
if(i == 0){
className += " active";
}

node.innerHTML += "<div class='"+className+"' data-key='"+item.obj.key+"'>"
+ fuzzysort.highlight(item[0]) + "</div>";
}
}, false);

//allow to select with arrow keys
document.addEventListener('keydown', function (e) {
if(document.querySelector('#global_search_results') == null
|| document.querySelector('.search-result') == null){
return;
}
var k = e.key;

if (k == "ArrowUp") {
var target = document.querySelector('.search-result.active');
var index = Array.from(target.parentNode.children).indexOf(target);
if(index > 0){
index--;
}
target.classList.remove('active');
var target2 =document.querySelector('#global_search_results').childNodes[index];
target2.classList.add('active');
e.preventDefault();
}
else if (k == "ArrowDown") {
var target = document.querySelector('.search-result.active');
var index = Array.from(target.parentNode.children).indexOf(target);
var total = target.parentNode.childElementCount;
if(index < total - 1){
index++;
}
target.classList.remove('active');
var target2 = document.querySelector('#global_search_results').childNodes[index];
target2.classList.add('active');
e.preventDefault();
}

}, false);
}

search() {
var _this = this;

//init DB
if(this.db === null) {
this.db = Object.keys(this.Base_gui.modules);
for(var i in this.db){
this.db[i] = {
key: this.db[i],
title: this.db[i].replace(/_/i, ' '),
};
}
}

var settings = {
title: 'Search',
params: [
{name: "search", title: "Search:", value: ""},
],
on_load: function (params, popup) {
var node = document.createElement("div");
node.id = 'global_search_results';
node.innerHTML = '';
popup.el.querySelector('.dialog_content').appendChild(node);
},
on_finish: function (params) {
//execute
var target = document.querySelector('.search-result.active');
if(target){
//execute
var key = target.dataset.key;
var class_object = this.Base_gui.modules[key];
var function_name = _this.get_function_from_path(key);

_this.POP.hide();
class_object[function_name]();
}
},
};
this.POP.show(settings);

//on input change
document.getElementById("pop_data_search").select();
}

get_function_from_path(path){
var parts = path.split("/");
var result = parts[parts.length - 1];
result = result.replace(/-/, '_');

return result;
}

}

export default Base_search_class;
4 changes: 1 addition & 3 deletions src/js/libs/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,7 @@ class Dialog_class {

if (code == "Escape") {
//escape
if (window.POP === this) {
this.hide(false);
}
this.hide(false);
}
}, false);

Expand Down
2 changes: 2 additions & 0 deletions src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Base_gui_class from './core/base-gui.js';
import Base_layers_class from './core/base-layers.js';
import Base_tools_class from './core/base-tools.js';
import Base_state_class from './core/base-state.js';
import Base_search_class from './core/base-search.js';
import File_open_class from './modules/file/open.js';
import File_save_class from './modules/file/save.js';
import * as Actions from './actions/index.js';
Expand All @@ -31,6 +32,7 @@ window.addEventListener('load', function (e) {
var Base_state = new Base_state_class();
var File_open = new File_open_class();
var File_save = new File_save_class();
var Base_search = new Base_search_class();

// Register singletons in app module
app.Actions = Actions;
Expand Down
2 changes: 2 additions & 0 deletions src/js/modules/help/shortcuts.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ class Help_shortcuts_class {
shortcuts() {
var settings = {
title: 'Keyboard Shortcuts',
className: 'shortcuts',
params: [
{title: "F", value: 'Auto Adjust Colors'},
{title: "F3", value: 'Search'},
{title: "Ctrl + C", value: 'Copy to Clipboard'},
{title: "D", value: 'Duplicate'},
{title: "S", value: 'Export'},
Expand Down
15 changes: 15 additions & 0 deletions src/js/modules/tools/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Base_search_class from './../../core/base-search.js';

class Tools_search_class {

constructor() {
this.Base_search = new Base_search_class();
}

search() {
this.Base_search.search();
}

}

export default Tools_search_class;

0 comments on commit fa6d7b6

Please sign in to comment.