Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full-text-search via Stork #327

Merged
merged 57 commits into from
Aug 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
b030b50
Added stork search
applejag Jul 28, 2022
116265a
Added search tmp docs
applejag Jul 28, 2022
46a5c0e
Fixed rg cmd
applejag Jul 28, 2022
6a29a32
Extracted to hooks
applejag Jul 30, 2022
22965ee
Removed search.md
applejag Jul 30, 2022
a5a67a2
Style so search results overlap notes
applejag Jul 30, 2022
b49c00b
Removed duplicate stylings
applejag Jul 30, 2022
809d5dd
Cleaned up JS a little
applejag Jul 30, 2022
79f23c4
Added shift 1px so borders align
applejag Jul 30, 2022
1a1c9e8
Get baseUrl from Emanote instead of <base>
applejag Jul 30, 2022
b470373
Moved JS & CSS to default/index.yaml
applejag Jul 31, 2022
69a2605
Add search snippets to docs
applejag Jul 31, 2022
a6c915d
Update default/templates/layouts/note.tpl
applejag Jul 31, 2022
b3489ff
Moved from hook to component, and enable via snippet
applejag Jul 31, 2022
64cc2f1
Fixed borders
applejag Jul 31, 2022
ba3363f
Add stork to nix shell
srid Aug 1, 2022
12cf3a1
Build stork.st index in Haskell
srid Aug 1, 2022
b216807
Fix autoformat
srid Aug 1, 2022
79f04dd
Fix hlint warning
srid Aug 1, 2022
62ff42e
Up ver
srid Aug 1, 2022
5dc1c38
nix: add stork as runtime dependency
srid Aug 1, 2022
dc82292
Added missing stork-search from headHtml
applejag Aug 2, 2022
47a7928
Merge branch 'feature/stork-search' of github.com:jilleJr/emanote int…
applejag Aug 2, 2022
b82c6ff
Advance ema
srid Aug 3, 2022
bcd9ee7
Revert "Added missing stork-search from headHtml"
applejag Aug 13, 2022
0b52f4a
Merge remote-tracking branch 'origin/master' into feature/stork-search
applejag Aug 13, 2022
d7d7cb5
Moved back to be in templates instead of snippet
applejag Aug 13, 2022
ace87ec
Merge branch 'feature/stork-search' of github.com:jilleJr/emanote int…
applejag Aug 13, 2022
460a1f2
Fix compilation
srid Aug 13, 2022
4957829
Fixed template
applejag Aug 13, 2022
d957084
lint fix
applejag Aug 13, 2022
a305339
nix: Use master branch of ema
srid Aug 13, 2022
f93922e
Added missing styling
applejag Aug 13, 2022
9f47d00
Changed to modal
applejag Aug 13, 2022
a5fe67b
Added listener for Ctrl+K
applejag Aug 13, 2022
2c2be46
Update nix inputs to use Stock 1.5.0
srid Aug 14, 2022
b308b8d
Use /dev/stdout instead of --output=-
applejag Aug 14, 2022
2b8ff25
nix: Unmark stork as broken (on intel mac only)
srid Aug 14, 2022
0d96667
Added hotkeys Cmd+K and Esc
applejag Aug 14, 2022
6c5c604
refactor: rename module
srid Aug 14, 2022
2f603bb
Cache stork index for reuse (when notes haven't been changed)
srid Aug 14, 2022
e683c78
Refactor: re-organize around, do newtype wrappers
srid Aug 14, 2022
084b873
Log the time it took for stork to run (1 second here)
srid Aug 14, 2022
dbdef65
remove debug
srid Aug 14, 2022
415c4af
Exclude tvar modification from the measure
srid Aug 14, 2022
b26171d
Group stork templates under components/stork
srid Aug 16, 2022
029609d
design: use icon to initiate search in all 3 places (note, book, brea…
srid Aug 17, 2022
92bacc8
Update ema
srid Aug 19, 2022
2de10a8
Inc major ver
srid Aug 19, 2022
1374943
Format!
srid Aug 19, 2022
a383d1c
Workaround the unicode issue with tomland
srid Aug 19, 2022
5959f67
docs: add full-text search
srid Aug 19, 2022
ebaa0b6
refactor: merge stork js/css into a single file, and include that in …
srid Aug 21, 2022
1bde671
add right padding to search icon in mobile view of note layout
srid Aug 21, 2022
f83d1ca
remove close button
srid Aug 21, 2022
c564971
Namespace the stork JS functions
srid Aug 21, 2022
b97f690
remove redundant
srid Aug 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions default/templates/base.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<apply template="/templates/hooks/more-head" />

<head-main />
<apply template="components/stork/stork-search-head" />
</head>

<!-- DoNotFormat -->
Expand All @@ -44,6 +45,7 @@

<body class="${bodyClass}">
<body-main />
<apply template="components/stork/stork-search" />
</body>

</html>
4 changes: 4 additions & 0 deletions default/templates/components/breadcrumbs.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
</ema:breadcrumbs>
</ul>
</div>
<button class="inline px-2 py-1 bg-gray-50 outline-none cursor-pointer focus:outline-none"
title="Search (Ctrl+K)" type="button" onclick="toggleSearch()">
<apply template="stork/stork-icon" />
</button>
<button
class="inline px-2 py-1 text-white bg-${theme}-600 outline-none cursor-pointer focus:outline-none"
title="Toggle sidebar" type="button" onclick="toggleHidden('sidebar')">
Expand Down
5 changes: 5 additions & 0 deletions default/templates/components/stork/stork-icon.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" style="width: 1rem;" class="hover:text-${theme}-700" f
fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
63 changes: 63 additions & 0 deletions default/templates/components/stork/stork-search-head.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<link rel="stylesheet" href="https://files.stork-search.net/releases/v1.5.0/flat.css" />
<!-- Custom Stork-search styling for Emanote -->
<style>
#stork-search-container {
z-index: 1000;
background-color: rgb(15 23 42/.8);
}

.stork-overflow-hidden-important {
overflow: hidden !important;
}
</style>


<script src="https://files.stork-search.net/releases/v1.5.0/stork.js"></script>
<ema:metadata>
<with var="template">
<script data-emanote-base-url="${value:baseUrl}">
window.emanote = {};
window.emanote.stork = {
searchShown: false,
toggleSearch: function () {
document.getElementById('stork-search-container').classList.toggle('hidden');
window.emanote.stork.searchShown = document.body.classList.toggle('stork-overflow-hidden-important');
if (window.emanote.stork.searchShown) {
document.getElementById('stork-search-input').focus();
}
},
clearSearch: function () {
document.getElementById('stork-search-container').classList.add('hidden');
document.body.classList.remove('stork-overflow-hidden-important');
window.emanote.stork.searchShown = false;
},

init: function () {
const indexName = 'emanote-search'; // used to match input[data-stork] attribute value
const baseUrl = document.currentScript.getAttribute('data-emanote-base-url') || '/';
const indexUrl = baseUrl + '-/stork.st';
if (document.readyState !== 'complete') {
window.addEventListener('load', function () {
stork.register(indexName, indexUrl);
});

document.addEventListener('keydown', event => {
if (window.emanote.stork.searchShown && event.key === 'Escape') {
window.emanote.stork.clearSearch();
event.preventDefault();
} else if ((event.key == 'k' || event.key == 'K') && (event.ctrlKey || event.metaKey)) {
window.emanote.stork.toggleSearch();
event.preventDefault();
}
});
} else {
// Override existing on Ema's hot-reload
stork.register(indexName, indexUrl, { forceOverwrite: true });
}
}
};

window.emanote.stork.init();
</script>
</with>
</ema:metadata>
12 changes: 12 additions & 0 deletions default/templates/components/stork/stork-search.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div id="stork-search-container"
class="hidden fixed w-screen h-screen inset-0 backdrop-filter backdrop-blur-sm">
<div class="fixed w-screen h-screen inset-0" onclick="window.emanote.stork.toggleSearch()"></div>

<div class="container mx-auto p-10 mt-10">
<div class="stork-wrapper-flat container mx-auto">
<input id="stork-search-input" data-stork="emanote-search" class="stork-input"
placeholder="Search (Ctrl+K) ..." />
<div data-stork="emanote-search-output" class="stork-output"></div>
</div>
</div>
</div>
5 changes: 4 additions & 1 deletion default/templates/layouts/book.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
<nav id="sidebar"
class="flex-shrink hidden leading-relaxed md:block md:sticky md:top-0 md:h-full md:w-48 xl:w-64">
<div class="px-2 py-2 text-gray-800">

<div id="indexing-links" class="flex flex-row float-right p-2 space-x-2 text-gray-500">
<a href="${ema:tagIndexUrl}" title="View tags">
<svg style="width: 1rem;" class="hover:text-${theme}-700" fill="none"
Expand All @@ -29,6 +28,10 @@
</path>
</svg>
</a>
<a title="Search (Ctrl+K)" class="cursor-pointer"
onclick="window.emanote.stork.toggleSearch()">
<apply template="components/stork/stork-icon" />
</a>
</div>

<div id="site-logo" class="pl-2">
Expand Down
10 changes: 9 additions & 1 deletion default/templates/layouts/note.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@
<div class="${containerClass}">
<div class="mt-2 md:mt-4">
<apply template="components/note-uptree" />
<div class="md:shadow-2xl md:mb-8">

<div class="relative md:shadow-2xl md:mb-8">

<div class="absolute -top-6 right-1 md:right-0 flex flex-row items-center justify-center">
<a title="Search (Ctrl+K)" class="cursor-pointer"
onclick="window.emanote.stork.toggleSearch()">
<apply template="components/stork/stork-icon" />
</a>
</div>
<div class="flex-1 w-full overflow-x-auto bg-white">
<main class="px-4 py-4">
<apply template="components/note-title" />
Expand Down
5 changes: 5 additions & 0 deletions docs/guide/search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Full-text search

Emanote provides client-side full-text search using [Stork](https://stork-search.net/)[^1]. The keyboard shortcut `Ctrl+K` (or `⌘K` on macOS) can be used to access the search input. Search should work in both live server and the statically generated site.

[^1]: The Stork index file can be accessed at [`-/stork.st`](-/stork.st).
9 changes: 7 additions & 2 deletions emanote.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 2.4
name: emanote
version: 0.6.23.1
version: 0.7.0.0
license: AGPL-3.0-only
copyright: 2021 Sridhar Ratnakumar
maintainer: [email protected]
Expand Down Expand Up @@ -103,7 +103,7 @@ common library-common
, data-default
, dependent-sum
, directory
, ema >=0.7.2
, ema >=0.8
, filepath
, filepattern
, fsnotify
Expand All @@ -126,15 +126,18 @@ common library-common
, pandoc-types
, parsec
, path-tree >=0.2
, process-extras
, profunctors
, relude >=1.0
, shower
, some
, stm
, tagged
, tagtree
, tailwind >=0.3
, text
, time
, tomland
, unionmount >=0.2
, unliftio
, unordered-containers
Expand Down Expand Up @@ -167,6 +170,8 @@ library
Emanote.Model.QuerySpec
Emanote.Model.SData
Emanote.Model.StaticFile
Emanote.Model.Stork
Emanote.Model.Stork.Index
Emanote.Model.Task
Emanote.Model.Title
Emanote.Model.Type
Expand Down
26 changes: 13 additions & 13 deletions flake.lock

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

4 changes: 4 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
haskell-flake.flakeModule
./nix/emanote.nix
./nix/docker.nix
./nix/stork.nix
];
perSystem = { pkgs, inputs', self', ... }: {
haskellProjects.default = {
Expand All @@ -35,6 +36,7 @@
ormolu;
inherit (inputs'.tailwind-haskell.packages)
tailwind;
inherit (self'.packages) stork;
};
source-overrides = {
inherit (inputs)
Expand All @@ -48,6 +50,8 @@
inherit (inputs'.tailwind-haskell.packages)
tailwind;
};
modifier = drv: with pkgs.haskell.lib;
addBuildDepends drv [ self'.packages.stork ];
};
packages.test =
pkgs.runCommand "emanote-test" { } ''
Expand Down
10 changes: 10 additions & 0 deletions nix/stork.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{ ... }:

{
perSystem = { system, pkgs, ... }: {
packages.stork =
# Stork is marked as broken on intel mac, but it does work.
# Unfortunately we cannot test this code PATH due to lack of CI for intel mac (#335).
if system == "x86_64-darwin" then pkgs.stork.overrideAttrs (_oa: { meta.broken = false; }) else pkgs.stork;
};
}
2 changes: 1 addition & 1 deletion src/Emanote.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ instance IsRoute SiteRoute where
instance EmaSite SiteRoute where
type SiteArg SiteRoute = EmanoteConfig
siteInput = emanoteSiteInput
siteOutput rp m r = pure $ View.emanoteSiteOutput rp m r
siteOutput = View.emanoteSiteOutput

defaultEmanoteConfig :: CLI.Cli -> EmanoteConfig
defaultEmanoteConfig cli =
Expand Down
30 changes: 30 additions & 0 deletions src/Emanote/Model/Stork.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module Emanote.Model.Stork
( renderStorkIndex,
)
where

import Control.Monad.Logger (MonadLoggerIO)
import Data.IxSet.Typed qualified as Ix
import Emanote.Model.Note qualified as N
import Emanote.Model.Stork.Index (File (File), Input (Input), readOrBuildStorkIndex)
import Emanote.Model.Title qualified as Tit
import Emanote.Model.Type (Model)
import Emanote.Model.Type qualified as M
import Emanote.Route qualified as R
import Emanote.Source.Loc qualified as Loc
import Optics.Core ((^.))
import Relude
import System.FilePath ((</>))

renderStorkIndex :: (MonadIO m, MonadLoggerIO m) => Model -> m LByteString
renderStorkIndex model = do
readOrBuildStorkIndex (model ^. M.modelStorkIndex) (Input $ storkFiles model)

storkFiles :: Model -> [File]
storkFiles model =
let baseDir = Loc.locPath . Loc.primaryLayer $ model ^. M.modelLayers
in Ix.toList (model ^. M.modelNotes) <&> \note ->
File
((baseDir </>) $ R.withLmlRoute R.encodeRoute $ note ^. N.noteRoute)
(toText $ R.encodeRoute $ N.noteHtmlRoute note)
(Tit.toPlain $ note ^. N.noteTitle)
Loading