Skip to content

Commit

Permalink
add fuzzy search and result stats, improve styles
Browse files Browse the repository at this point in the history
  • Loading branch information
blurymind committed Sep 13, 2024
1 parent 4b595cf commit eabfbcb
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 111 deletions.
85 changes: 42 additions & 43 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<body>
<script src="./public/libs/bondage.min.js"></script>
<script src="./public/libs/ink-full.js"></script>
<script src="./public/libs/uFuzzy.iife.min.js"></script>

<!-- Web components - see index.js importing web-components.js-->
<toast-component></toast-component>
Expand All @@ -20,11 +21,50 @@

<!-- Container -->
<div id="app">

<!-- app-opened-documents -->
<div class="file-tabs" id="fileTabsTray">
<span style="border-radius: 2px; padding: 0 5px;margin-right: 5px" class="bbcode-button" data-bind="click:app.data.trySaveCurrent, text:`${data.isDocumentDirty() ? '💾':'✅'}`"></span>
<button class="bbcode-button" data-bind="click: function(){
app.settings.fileTabsVisible(!app.settings.fileTabsVisible())
},css: {
active: !app.settings.fileTabsVisible(), rotated: !app.settings.fileTabsVisible()
}, attr: { title: `${data.appInstanceStates().length} files opened`}">=</button>
<div class="file-tabs-buttons" data-bind="css:{
collapsed: !app.settings.fileTabsVisible()
}, foreach: { data: data.appInstanceStates, as: 'state' }">
<button class="bbcode-button session-button" data-bind="
click:function(data, event) {
$root.data.loadDocumentStateTabFromIndex($index());
},
attr: {
title:
`${state.editingName}
contains ${state.nodes.length} node${state.nodes.length > 1 ? 's':''}
${state.lastStorageHost} HOST
${state.lastEditedUnix || ''}
`},
css: { active: $index() == app.settings.selectedFileTab()}
">
<span data-bind="text: state.editingName + `(${state.nodes.length})`"></span>
<!-- <span data-bind="click:function(e){-->
<!-- $root.data.deleteDocumentStateTab($index());-->
<!-- },clickBubble: false">[X]</span>-->
</button>
</div>
<div class="flex-wrap" style="justify-content: space-between;" data-bind="visible:app.settings.fileTabsVisible()">
<button class="bbcode-button" data-bind="click:function() {
data.deleteDocumentStateTab(app.settings.selectedFileTab())
}, visible: data.appInstanceStates().length > 1, attr: { title: `Close ${data.editingName()} file`}">-</button>
<button class="bbcode-button" data-bind="click:function() {
data.addDocumentStateTab()
}" title="Open new tab">+</button>
</div>
</div>

<!-- search form -->
<div class="app-search" id="appSearchTray">
<form class="menu" autocomplete="off" onkeypress="return event.keyCode != 13;">
<span class="app-search-field">
<span class="app-search-field" id="nodeSearchInputWrapper">
<input id="nodeSearchInput" type="search" class="search-field" placeholder="Search" autocomplete="off" oninput="app.ui.openNodeListMenu('open')" onmouseenter="app.ui.openNodeListMenu('open')">
<button id="nodeSearchClear" data-bind="click: app.clearSearch">×</button>
</span>
Expand Down Expand Up @@ -83,7 +123,6 @@
<span data-bind="click: function() { app.workspace.setZoom(2); }" title="Zoom 3:1"><svg class="icon icon-th icon-lg icon-fw"><use xlink:href="public/icons.svg#icon-th"></use></svg></span>
<span data-bind="click: function() { app.workspace.setZoom(1); }" title="Zoom 4:1"><svg class="icon icon-th icon-lg icon-fw"><use xlink:href="public/icons.svg#icon-th-small"></use></svg></span>
</div>

<!-- main menu -->
<div class="app-menu" id="appHeader">
<!-- File menu -->
Expand Down Expand Up @@ -181,46 +220,6 @@
</div> <!-- file menu -->
</div> <!-- app-menu -->

<!-- app-opened-documents -->
<div class="file-tabs" id="fileTabsTray">
<span style="border-radius: 2px; padding: 0 5px;margin-right: 5px" class="bbcode-button" data-bind="click:app.data.trySaveCurrent, text:`${data.isDocumentDirty() ? '💾':'✅'}`"></span>
<button class="bbcode-button" data-bind="click: function(){
app.settings.fileTabsVisible(!app.settings.fileTabsVisible())
},css: {
active: !app.settings.fileTabsVisible(), rotated: !app.settings.fileTabsVisible()
}, attr: { title: `${data.appInstanceStates().length} files opened`}">=</button>
<div class="file-tabs-buttons" data-bind="css:{
collapsed: !app.settings.fileTabsVisible()
}, foreach: { data: data.appInstanceStates, as: 'state' }">
<button class="bbcode-button session-button" data-bind="
click:function(data, event) {
$root.data.loadDocumentStateTabFromIndex($index());
},
attr: {
title:
`${state.editingName}
contains ${state.nodes.length} node${state.nodes.length > 1 ? 's':''}
${state.lastStorageHost} HOST
${state.lastEditedUnix || ''}
`},
css: { active: $index() == app.settings.selectedFileTab()}
">
<span data-bind="text: state.editingName + `(${state.nodes.length})`"></span>
<!-- <span data-bind="click:function(e){-->
<!-- $root.data.deleteDocumentStateTab($index());-->
<!-- },clickBubble: false">[X]</span>-->
</button>
</div>
<div class="flex-wrap" style="justify-content: space-between;" data-bind="visible:app.settings.fileTabsVisible()">
<button class="bbcode-button" data-bind="click:function() {
data.deleteDocumentStateTab(app.settings.selectedFileTab())
}, visible: data.appInstanceStates().length > 1, attr: { title: `Close ${data.editingName()} file`}">-</button>
<button class="bbcode-button" data-bind="click:function() {
data.addDocumentStateTab()
}" title="Open new tab">+</button>
</div>
</div>

<!-- grid bg for snap to grid functionality -->
<canvas id="grid-canvas" class="grid-canvas"></canvas>

Expand Down
96 changes: 48 additions & 48 deletions src/js/classes/ui.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { data } from './data';
// const uFuzzy = require('@leeoniya/ufuzzy');
const opts = {intraMode: 1};
const uf = new uFuzzy(opts);

export const UI = function(app) {
const self = this;
Expand Down Expand Up @@ -216,58 +219,45 @@ export const UI = function(app) {
});
};

this.nodeSearchMatches = function(node, search, matchAll = false) {
var title = matchAll || $('.search-title input').is(':checked');
var body = matchAll || $('.search-body input').is(':checked');
var tags = matchAll || $('.search-tags input').is(':checked');

if (search.length === 0 || (!title && !body && !tags)) {
return {
matchTitle: false,
matchBody: false,
matchTags: false,
clearSearch: true,
};
} else {
var matchTitle =
title &&
node
.title()
.toLowerCase()
.indexOf(search) >= 0;
var matchBody =
body &&
node
.body()
.toLowerCase()
.indexOf(search) >= 0;
var matchTags =
tags &&
node
.tags()
.toLowerCase()
.indexOf(search) >= 0;
return { matchTitle, matchBody, matchTags, clearSearch: false };
}
};

this.findMatchingNodes = function(searchText) {
const title = $('.search-title input').is(':checked');
const body = $('.search-body input').is(':checked');
const tags = $('.search-tags input').is(':checked');

const searchNodesReversed = [...app.nodes()].reverse();
if(searchText.length === 0 || (!title && !body && !tags)) return searchNodesReversed;
const searchNodeTitles = [];
const searchNodeBody = [];
const searchNodeTags = [];
searchNodesReversed.map(node=> {
if (title) searchNodeTitles.push(node.title())
if (body) searchNodeBody.push(node.body())
if (tags) searchNodeTags.push(node.tags())
});

const matchTitle = uf.filter(searchNodeTitles, searchText);
// todo markup hints
// const titleInfo = uf.info(matchTitle, searchNodeTitles, searchText);
// const titleOrder = uf.sort(titleInfo, searchNodeTitles, searchText);
// let innerHTML = '';//should be array
// for (let i = 0; i < titleOrder.length; i++) {
// let infoIdx = titleOrder[i];
// innerHTML += uFuzzy.highlight(
// searchNodeTitles[titleInfo.idx[infoIdx]],
// titleInfo.ranges[infoIdx],
// ) + '<br>';
// }
// console.log({matchTitle, titleInfo, titleOrder, innerHTML})
const matchBody = uf.filter(searchNodeBody, searchText);
const matchTags = uf.filter(searchNodeTags, searchText);
const found = {
matchTitle: [],
matchBody: [],
matchTags: [],
matchTitle: matchTitle.map(idx => searchNodesReversed[idx]),
matchBody: matchBody.map(idx => searchNodesReversed[idx]),
matchTags: matchTags.map(idx => searchNodesReversed[idx]),
foundNodes: false,
clearSearch: searchText.length === 0 || (!title && !body && !tags)
};
[...app.nodes()].reverse().forEach(node => {
const { matchTitle, matchBody, matchTags } = app.ui.nodeSearchMatches(
node,
searchText,
true
);
if (matchTitle) found.matchTitle.push(node);
if (matchBody) found.matchBody.push(node);
if (matchTags) found.matchTags.push(node);
});

found.foundNodes =
found.matchTitle.length > 0 ||
found.matchBody.length > 0 ||
Expand Down Expand Up @@ -326,6 +316,10 @@ export const UI = function(app) {

// If there's no search query or nothing is found, simply return all nodes
if (!searchText) {
if(action !== 'link') {
document.getElementById('nodeSearchInputWrapper').style.borderLeft = '';
document.getElementById('nodeSearchInputWrapper').title = `total: ${app.nodes().length}`;
}
listAllNodes();
return;
}
Expand All @@ -342,6 +336,12 @@ export const UI = function(app) {
found.matchBody.forEach(node => {
this.createSearchMenuLine(node, action, rootMenu, 'body');
});
if(action !== 'link') {
document.getElementById('nodeSearchInputWrapper').style.borderLeft = found.foundNodes ? '1px solid red' : '';
const foundInfo = `${found.matchTitle.length > 0 ? `title:${found.matchTitle.length}`: ''}${found.matchBody.length > 0 ? ` body:${found.matchBody.length}`: ''}${found.matchTags.length > 0 ? ` tags:${found.matchTags.length}` : ''}`;
document.getElementById('nodeSearchInputWrapper').title = foundInfo;// todo move out
}

}
};

Expand Down
2 changes: 2 additions & 0 deletions src/public/libs/uFuzzy.iife.min.js

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

3 changes: 3 additions & 0 deletions src/public/themes/blueprint.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
:root {
--text-color: #2f919a;
}
/*-- Scrollbar ------------------------------------------------------------------ */

::-webkit-scrollbar-thumb:hover {
Expand Down
7 changes: 6 additions & 1 deletion src/public/themes/classic.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
:root {
--yarnBg: #baf5f2;
--yarnFg: #00dcff;
--text-color: #134347;
}

#app-bg {
Expand All @@ -17,6 +18,9 @@ a {
a:hover {
color: #000;
}
.styled-checkbox {
background-color: white;
}
.styled-checkbox>label>svg,
.bbcode-button>svg {
fill: #8a8a8a;
Expand Down Expand Up @@ -204,7 +208,8 @@ a:hover {
}

.app-search {
top: 0;
top: 34px;
left: 0px;
position: absolute;
width: 50%;
padding: 5px 10px 5px 5px;
Expand Down
5 changes: 3 additions & 2 deletions src/public/themes/dracula.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
.node .body::-webkit-scrollbar {
display: none;
}

:root {
--text-color: #fdffab;
}
/*-- Menu ------------------------------------------------------------------ */
.app-menu {
position: absolute;
Expand Down Expand Up @@ -64,7 +66,6 @@
opacity: 0.9;
background-color: #343746;
}

.menu .dropdown .search-field{
color: #f8f8f2;
background: #282a36;
Expand Down
Loading

0 comments on commit eabfbcb

Please sign in to comment.