- commit
- 21d48bd
- parent
- 68b23ca
- author
- Eric Bower
- date
- 2021-07-19 14:53:37 +0000 UTC
show tags under each plugin in plugin list
5 files changed,
+187,
-150
+89,
-0
1@@ -0,0 +1,89 @@
2+<script lang="ts">
3+ import qs from 'query-string';
4+ import { goto } from '$app/navigation';
5+
6+ import type { Plugin, Tag } from './types';
7+ import TagItem from './tag.svelte';
8+ import Icon from './icon.svelte';
9+ import Tooltip from '$lib/tooltip.svelte';
10+
11+ export let plugin: Plugin;
12+ export let tags: Tag[];
13+ export let html: string = '<div>readme not found</div>';
14+ const isPlugin = tags.find((t) => t.id === 'plugin');
15+
16+ function onSearch(curSearch: string) {
17+ const query = qs.parseUrl(window.location.search);
18+ const s = encodeURIComponent(curSearch);
19+ query.query.search = s;
20+ goto(`/${qs.stringifyUrl(query)}`);
21+ }
22+</script>
23+
24+<div class="meta">
25+ <div class="tags_view">
26+ {#each tags as tag}
27+ <TagItem {tag} {onSearch} showCount={false} />
28+ {/each}
29+ </div>
30+ <div class="metrics">
31+ <Tooltip tip="stars" bottom>
32+ <div class="metric"><Icon icon="star" /> <span>{plugin.stars}</span></div>
33+ </Tooltip>
34+ <Tooltip tip="open issues" bottom>
35+ <div class="metric"><Icon icon="alert-circle" /> <span>{plugin.openIssues}</span></div>
36+ </Tooltip>
37+ <Tooltip tip="subscribers" bottom>
38+ <div class="metric"><Icon icon="users" /> <span>{plugin.subscribers}</span></div>
39+ </Tooltip>
40+ <Tooltip tip="forks" bottom>
41+ <div class="metric"><Icon icon="git-branch" /> <span>{plugin.forks}</span></div>
42+ </Tooltip>
43+ </div>
44+ {#if isPlugin}
45+ <div class="install">
46+ <h3>packer</h3>
47+ <pre><code>require('packer').startup(function()
48+ use '{plugin.id}'
49+end)</code></pre>
50+ </div>
51+ <div class="install">
52+ <h3>paq</h3>
53+ <pre><code>require "paq" {
54+ '{plugin.id}'
55+}</code></pre>
56+ </div>
57+ {/if}
58+ <hr />
59+</div>
60+{@html html}
61+
62+<style>
63+ :global(img) {
64+ max-width: 100%;
65+ height: auto;
66+ }
67+
68+ .meta {
69+ margin-bottom: 20px;
70+ }
71+
72+ .metrics {
73+ display: flex;
74+ justify-content: space-between;
75+ }
76+
77+ .metric {
78+ display: flex;
79+ align-items: center;
80+ cursor: pointer;
81+ }
82+
83+ .tags_view {
84+ margin-bottom: 10px;
85+ }
86+
87+ .install {
88+ margin-top: 10px;
89+ }
90+</style>
+65,
-74
1@@ -1,89 +1,80 @@
2 <script lang="ts">
3- import qs from 'query-string';
4- import { goto } from '$app/navigation';
5-
6- import type { Plugin, Tag } from './types';
7- import TagView from './tag.svelte';
8- import Icon from './icon.svelte';
9- import Tooltip from '$lib/tooltip.svelte';
10-
11- export let plugin: Plugin;
12- export let tags: Tag[];
13- export let html: string = '<div>readme not found</div>';
14- const isPlugin = tags.find((t) => t.id === 'plugin');
15-
16- function onSearch(curSearch: string) {
17- const query = qs.parseUrl(window.location.search);
18- const s = encodeURIComponent(curSearch);
19- query.query.search = s;
20- goto(`/${qs.stringifyUrl(query)}`);
21- }
22+import type { Plugin, Tag } from './types';
23+import Tooltip from './tooltip.svelte';
24+import Icon from './icon.svelte';
25+import TagItem from './tag.svelte';
26+export let plugin: Plugin;
27+export let tags: Tag[];
28+export let onSearch: (t: string) => any = (_: string) => {};
29 </script>
30
31-<div class="meta">
32- <div class="tags_view">
33- {#each tags as tag}
34- <TagView {tag} {onSearch} />
35- {/each}
36- </div>
37- <div class="metrics">
38- <Tooltip tip="stars" bottom>
39- <div class="metric"><Icon icon="star" /> <span>{plugin.stars}</span></div>
40- </Tooltip>
41- <Tooltip tip="open issues" bottom>
42- <div class="metric"><Icon icon="alert-circle" /> <span>{plugin.openIssues}</span></div>
43- </Tooltip>
44- <Tooltip tip="subscribers" bottom>
45- <div class="metric"><Icon icon="users" /> <span>{plugin.subscribers}</span></div>
46- </Tooltip>
47- <Tooltip tip="forks" bottom>
48- <div class="metric"><Icon icon="git-branch" /> <span>{plugin.forks}</span></div>
49- </Tooltip>
50+
51+<div class="container">
52+ <div class="header">
53+ <h2 class="item_header">
54+ <a href="/plugin/{plugin.username}/{plugin.repo}">{plugin.repo}</a>
55+ </h2>
56+ <div class="metrics">
57+ <Tooltip tip="stars" bottom>
58+ <div class="metric-item"><Icon icon="star" /> <span>{plugin.stars}</span></div>
59+ </Tooltip>
60+ <Tooltip tip="open issues" bottom>
61+ <div class="metric-item">
62+ <Icon icon="alert-circle" /> <span>{plugin.openIssues}</span>
63+ </div>
64+ </Tooltip>
65+ </div>
66 </div>
67- {#if isPlugin}
68- <div class="install">
69- <h3>packer</h3>
70- <pre><code>require('packer').startup(function()
71- use '{plugin.id}'
72-end)</code></pre>
73+ <div class="desc">
74+ {plugin.description}
75 </div>
76- <div class="install">
77- <h3>paq</h3>
78- <pre><code>require "paq" {
79- '{plugin.id}'
80-}</code></pre>
81+ <div class="tags">
82+ {#each tags as tag}
83+ <TagItem {tag} showCount={false} {onSearch} />
84+ {/each}
85 </div>
86- {/if}
87- <hr />
88 </div>
89-{@html html}
90
91 <style>
92- :global(img) {
93- max-width: 100%;
94- height: auto;
95- }
96+.container {
97+ display: flex;
98+ flex-direction: column;
99+ padding: 15px 5px;
100+ height: 140px;
101+ border-bottom: 1px solid var(--primary-color);
102+}
103+
104+.header {
105+ display: flex;
106+ align-items: center;
107+ margin-bottom: 5px;
108+}
109
110- .meta {
111- margin-bottom: 20px;
112- }
113+.desc {
114+ margin-top: 5px;
115+}
116
117- .metrics {
118- display: flex;
119- justify-content: space-between;
120- }
121+.item_header {
122+ flex: 1;
123+ display: flex;
124+ align-items: center;
125+}
126
127- .metric {
128- display: flex;
129- align-items: center;
130- cursor: pointer;
131- }
132+.metrics {
133+ width: 150px;
134+ min-width: 150px;
135+ display: flex;
136+ justify-content: space-between;
137+}
138
139- .tags_view {
140- margin-bottom: 10px;
141- }
142+.metric-item {
143+ display: flex;
144+ justify-content: center;
145+ align-items: center;
146+ cursor: pointer;
147+}
148
149- .install {
150- margin-top: 10px;
151- }
152+.tags {
153+ margin-top: 5px;
154+}
155 </style>
+2,
-1
1@@ -11,10 +11,11 @@
2
3 export let tag: Tag;
4 export let onSearch: (t: string) => any = (_: string) => {};
5+ export let showCount: boolean = true;
6 </script>
7
8 <span class="tag {findColor(tag)}" on:click={() => onSearch(`tag:${tag.id}`)}>
9- {tag.id} x {tag.count}
10+ {tag.id}{#if showCount} x {tag.count}{/if}
11 </span>
12
13 <style>
+30,
-74
1@@ -6,12 +6,13 @@
2
3 export async function load() {
4 const pluginDb = db.plugins as any;
5- const { plugins, tags } = derivePluginData(pluginDb);
6+ const { plugins, tags, tagDb } = derivePluginData(pluginDb);
7
8 return {
9 props: {
10 plugins,
11 tags,
12+ tagDb
13 },
14 };
15 }
16@@ -21,10 +22,10 @@
17 import qs from 'query-string';
18 import { goto } from '$app/navigation';
19 import { page } from '$app/stores';
20- import type { Plugin, Tag } from '$lib/types';
21- import TagView from '$lib/tag.svelte';
22+ import type { Plugin, Tag, TagMap } from '$lib/types';
23+ import TagItem from '$lib/tag.svelte';
24 import Icon from '$lib/icon.svelte';
25- import Tooltip from '$lib/tooltip.svelte';
26+ import PluginItem from '$lib/plugin.svelte';
27
28 let timer: NodeJS.Timeout;
29 const debounce = (fn: (v: string) => any) => {
30@@ -76,6 +77,11 @@
31 return plugins.filter(onFilter);
32 }
33
34+ export let tagDb: TagMap = {};
35+ function getTags(tags: string[]): Tag[] {
36+ return tags.map((t) => tagDb[t]).filter(Boolean);
37+ }
38+
39 let search = '';
40 page.subscribe(({ query }) => {
41 search = decodeURIComponent(query.get('search') || '');
42@@ -89,7 +95,7 @@
43 <div class="container">
44 <div class="intro">
45 <h1 id="logo">
46- Neovim Awesome
47+ neovim awesome
48 <a href="https://github.com/neurosnap/neovim-awesome" target="_blank">
49 <Icon icon="github" />
50 </a>
51@@ -111,34 +117,17 @@
52 {/if}
53 </div>
54
55- <div class="tags_view">
56+ <div class="sidebar">
57+ <div class="desc">Search through our curated list of neovim plugins</div>
58 {#each tags as tag}
59- <TagView {tag} {onSearch} />
60+ <TagItem {tag} {onSearch} />
61 {/each}
62 </div>
63- <div class="plugins_view">
64+ <div class="plugins">
65+ <div class="search_results">{results.length} results</div>
66 <div class="plugins_list">
67 {#each results as plugin}
68- <div class="plugin">
69- <div class="plugin_top">
70- <h2 class="plugin_item_header">
71- <a href="/plugin/{plugin.username}/{plugin.repo}">{plugin.repo}</a>
72- </h2>
73- <div class="plugin_metrics">
74- <Tooltip tip="stars" bottom>
75- <div class="metric"><Icon icon="star" /> <span>{plugin.stars}</span></div>
76- </Tooltip>
77- <Tooltip tip="open issues" bottom>
78- <div class="metric">
79- <Icon icon="alert-circle" /> <span>{plugin.openIssues}</span>
80- </div>
81- </Tooltip>
82- </div>
83- </div>
84- <div class="plugin_desc">
85- {plugin.description}
86- </div>
87- </div>
88+ <PluginItem {plugin} tags={getTags(plugin.tags)} onSearch={onSearch} />
89 {/each}
90 </div>
91 </div>
92@@ -149,6 +138,10 @@
93 </svelte:head>
94
95 <style>
96+ .desc {
97+ margin-bottom: 5px;
98+ }
99+
100 .search_view {
101 grid-column: 2;
102 grid-row: 1;
103@@ -175,6 +168,10 @@
104 padding-right: 30px;
105 }
106
107+ .search_results {
108+ margin: 5px 0;
109+ }
110+
111 .container {
112 height: 100vh;
113 display: grid;
114@@ -198,7 +195,7 @@
115 margin-left: 15px;
116 }
117
118- .tags_view {
119+ .sidebar {
120 grid-column: 1;
121 grid-row: 2;
122 padding: 0 10px;
123@@ -206,54 +203,13 @@
124 overflow-y: scroll;
125 }
126
127- .plugin {
128- display: flex;
129- flex-direction: column;
130- padding: 15px;
131- height: 110px;
132- border-bottom: 1px solid var(--primary-color);
133- }
134-
135- .plugin_top {
136- display: flex;
137- align-items: center;
138- margin-bottom: 5px;
139- }
140-
141- .plugin_desc {
142- margin-top: 5px;
143- }
144-
145- .plugin_item_header {
146- flex: 1;
147- display: flex;
148- align-items: center;
149- }
150-
151- .plugin_metrics {
152- width: 150px;
153- min-width: 150px;
154- display: flex;
155- justify-content: space-between;
156- }
157-
158- .metric {
159- display: flex;
160- justify-content: center;
161- align-items: center;
162- cursor: pointer;
163- }
164-
165- .plugins_view {
166- display: flex;
167- align-items: center;
168- flex-direction: column;
169+ .plugins {
170 grid-column: 2;
171 grid-row: 2;
172- height: calc(100vh - 50px);
173 }
174
175 .plugins_list {
176+ height: calc(100vh - 50px);
177 width: 100%;
178 overflow-y: auto;
179 overflow-x: hidden;
180@@ -265,7 +221,7 @@
181 }
182
183 #logo,
184- .tags_view {
185+ .sidebar {
186 display: none;
187 }
188
189@@ -274,7 +230,7 @@
190 padding: 0 10px;
191 }
192
193- .plugins_view {
194+ .plugins {
195 grid-column: 1;
196 }
197 }
1@@ -23,7 +23,7 @@
2
3 <script lang="ts">
4 import type { Plugin, Tag } from '$lib/types';
5- import PluginView from '$lib/plugin.svelte';
6+ import PluginView from '$lib/plugin-view.svelte';
7 import Icon from '$lib/icon.svelte';
8
9 export let plugin: Plugin;