- commit
- 2d4cfdd
- parent
- 1c55a9a
- author
- Eric Bower
- date
- 2021-09-01 04:51:24 +0000 UTC
ability to sort by created and updated at
6 files changed,
+85,
-21
+2,
-1
1@@ -68,7 +68,8 @@
2 "desc": "New to lua? Start with us and learn!",
3 "date": "2021-07-22",
4 "media": "/lua-script.png"
5- }, {
6+ },
7+ {
8 "text": "Let's create a Neovim plugin using Treesitter and Lua",
9 "tags": ["learn"],
10 "url": "https://www.youtube.com/watch?v=dPQfsASHNkg",
+8,
-2
1@@ -42,8 +42,14 @@
2 </Tooltip>
3 </div>
4 <div class="timestamps">
5- <div><h5 class="ts-header">CREATED</h5><h2>{format(new Date(plugin.createdAt))}</h2></div>
6- <div><h5 class="ts-header">UPDATED</h5><h2>{relativeTimeFromDates(new Date(plugin.updatedAt))}</h2></div>
7+ <div>
8+ <h5 class="ts-header">CREATED</h5>
9+ <h2>{format(new Date(plugin.createdAt))}</h2>
10+ </div>
11+ <div>
12+ <h5 class="ts-header">UPDATED</h5>
13+ <h2>{relativeTimeFromDates(new Date(plugin.updatedAt))}</h2>
14+ </div>
15 </div>
16 {#if isPlugin}
17 <div class="install">
+8,
-0
1@@ -3,6 +3,7 @@
2 import Tooltip from './tooltip.svelte';
3 import Icon from './icon.svelte';
4 import TagItem from './tag.svelte';
5+ import { relativeTimeFromDates } from './date';
6 export let plugin: Plugin;
7 export let tags: Tag[];
8 export let onSearch: (t: string) => any = (_: string) => {};
9@@ -27,6 +28,9 @@
10 </Tooltip>
11 </div>
12 </div>
13+ <div class="date">
14+ updated {relativeTimeFromDates(new Date(plugin.updatedAt))}
15+ </div>
16 <div class="desc">
17 {plugin.description}
18 </div>
19@@ -47,6 +51,10 @@
20 border-bottom: 1px solid var(--primary-color);
21 }
22
23+ .date {
24+ font-size: 14px;
25+ }
26+
27 .header {
28 display: flex;
29 align-items: center;
+3,
-2
1@@ -39,8 +39,9 @@
2 <h3>Where do we get our content from?</h3>
3 <p>
4 As of right now, most of our data is scraped from github. You can find our scrape script
5- <a href="https://github.com/neurosnap/neovimcraft/blob/main/scripts/scrape.ts" target="_blank"
6- >here</a
7+ <a
8+ href="https://github.com/neurosnap/neovimcraft/blob/main/scripts/scrape.ts"
9+ target="_blank">here</a
10 >.
11 </p>
12 <h3>How can I submit a plugin or resource to this project?</h3>
+12,
-11
1@@ -50,23 +50,24 @@
2 I've been compiling a list of guides that help people build and use lua plugins for neovim.
3 </p>
4 {#each articles as link}
5- <div class="article">
6+ <div class="article">
7 {#if link.media}
8 {#if link.media.includes('youtube')}
9- <iframe
10- width="560"
11- height="315"
12- src="{link.media}"
13- title="YouTube video player"
14- frameborder="0"
15- allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
16- allowfullscreen></iframe>
17+ <iframe
18+ width="560"
19+ height="315"
20+ src={link.media}
21+ title="YouTube video player"
22+ frameborder="0"
23+ allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
24+ allowfullscreen
25+ />
26 {:else}
27 <a href={link.url} target="_blank">
28 <img src={link.media} alt={link.text} class="media" />
29 </a>
30- {/if}
31- {/if}
32+ {/if}
33+ {/if}
34 <div class="article-header">
35 <h2>
36 <a href={link.url} target="_blank">{link.text}</a>
+52,
-5
1@@ -47,13 +47,38 @@
2 }
3 }
4
5+ const sortNum = (a: number, b: number) => b - a;
6+ const sortDateStr = (a: string, b: string) => {
7+ const dateA = new Date(a).getTime();
8+ const dateB = new Date(b).getTime();
9+ return dateB - dateA;
10+ };
11+
12+ function onSort(by: keyof Plugin) {
13+ if (by === 'createdAt') {
14+ return (a: Plugin, b: Plugin) => sortDateStr(a.createdAt, b.createdAt);
15+ }
16+ if (by === 'updatedAt') {
17+ return (a: Plugin, b: Plugin) => sortDateStr(a.updatedAt, b.updatedAt);
18+ }
19+ return (a: Plugin, b: Plugin) => sortNum(a.stars, b.stars);
20+ }
21+
22 function clearSearch() {
23 goto('/');
24 document.getElementById('search').focus();
25 }
26
27- function filterPlugins({ search, plugins }: { search: string; plugins: Plugin[] }): Plugin[] {
28- if (!search) return plugins;
29+ function filterPlugins({
30+ search,
31+ plugins,
32+ sort,
33+ }: {
34+ search: string;
35+ plugins: Plugin[];
36+ sort: keyof Plugin;
37+ }): Plugin[] {
38+ if (!search) return plugins.sort(onSort(sort));
39
40 const onFilter = (plugin: Plugin) => {
41 if (search.includes('tag:')) {
42@@ -63,18 +88,23 @@
43 return plugin.id.toLocaleLowerCase().includes(search.toLocaleLowerCase());
44 };
45
46- return plugins.filter(onFilter);
47+ return plugins.filter(onFilter).sort(onSort(sort));
48 }
49
50 export let tagDb: TagMap = {};
51 function getTags(tags: string[]): Tag[] {
52 return tags.map((t) => tagDb[t]).filter(Boolean);
53 }
54-
55+
56 $: search = decodeURIComponent($page.query.get('search') || '');
57+ let sort = 'stars' as keyof Plugin;
58+ const setSort = (e: any, nextSort: keyof Plugin) => {
59+ e.preventDefault();
60+ sort = nextSort;
61+ };
62 export let plugins: Plugin[] = [];
63 export let tags: Tag[] = [];
64- $: filterTotal = filterPlugins({ search, plugins });
65+ $: filterTotal = filterPlugins({ search, plugins, sort });
66 </script>
67
68 <svelte:head>
69@@ -118,6 +148,23 @@
70 <div class="plugins">
71 <div class="plugins_list" id="plugins_list">
72 <div class="search_results">{filterTotal.length} results</div>
73+ <div>
74+ {#if sort === 'stars'}
75+ stars
76+ {:else}
77+ <a href="#" on:click={(e) => setSort(e, 'stars')}>stars</a>
78+ {/if}
79+ {#if sort === 'createdAt'}
80+ created
81+ {:else}
82+ <a href="#" on:click={(e) => setSort(e, 'createdAt')}>created</a>
83+ {/if}
84+ {#if sort === 'updatedAt'}
85+ updated
86+ {:else}
87+ <a href="#" on:click={(e) => setSort(e, 'updatedAt')}>updated</a>
88+ {/if}
89+ </div>
90 {#each filterTotal as plugin}
91 <PluginItem {plugin} tags={getTags(plugin.tags)} {onSearch} />
92 {/each}