@@ -44,6 +44,79 @@ <h4 style="margin: 0;">Forums</h4>
4444
4545< hr >
4646
47+ {# Crates #}
48+
49+
50+ < section >
51+ < div class ="container-full ">
52+ < h2 > Audio crates</ h2 >
53+ < div class ="filters tags "> </ div >
54+ </ div >
55+ < div class ="crates " id ="crates ">
56+ {% set crates = load_data(path="content/crates.toml") %}
57+ {% for source, crates in crates.crates | group_by(attribute="source") %}
58+
59+ {% for crate in crates %}
60+
61+ {# Obtain API data #}
62+ {% if source == "github" %}
63+ {# Get github API page to pull information #}
64+ {% set data = load_data(url="https://api.github.com/repos/"~crate.key, format="json") %}
65+ {% set name = data.name %}
66+ {% set description = data.description %}
67+ {% set url = data.svn_url %}
68+ {% set keywords = data.topics %}
69+
70+ {% elif source == "crates" %}
71+ {# Get crates API page to pull information #}
72+ {% set data = load_data(url="https://crates.io/api/v1/crates/"~crate.key, format="json") %}
73+ {% set name = data.crate.name %}
74+ {% set description = data.crate.description %}
75+ {% set url = "https://crates.io/crates/"~name %}
76+ {% set keywords = data.crate.keywords %}
77+
78+ {% endif %}
79+
80+ < div class ='crate ' data-keywords ='{{ keywords | join(sep=" ") }} '>
81+ < a target =" _blank " href ={{url}} >
82+ < h4 >
83+ < pre > {{ name }}</ pre >
84+ </ h4 >
85+ </ a >
86+ < p > {{ description }}</ p >
87+
88+ < div class ="tags ">
89+ {% for keyword in keywords %}
90+ < span class ="filter-tag tag " data-keyword ={{keyword}} > {{keyword}}</ span >
91+ {% endfor %}
92+ </ div >
93+ {# < div class ="details ">
94+ < div class ="stars "> {{ crate.stargazers_count }} ☆</ div >
95+ </ div > #}
96+ </ div >
97+ {% endfor %}
98+ {% endfor %}
99+ </ div >
100+
101+ {# < div class ="crates ">
102+ {% set crates = load_data(url=config.extra.repos_url, format="json") %}
103+ {% for crate in crates | sort(attribute="updated_at") | reverse %}
104+ < div class ="crate ">
105+ < a target ="_blank " href ={{crate.svn_url}} >
106+ < h5 >
107+ < pre > {{ crate.name }}</ pre >
108+ </ h5 >
109+ </ a >
110+ < div class ="details ">
111+ < div class ="stars "> {{ crate.stargazers_count }} ☆</ div >
112+ </ div >
113+ </ div >
114+ {% endfor %}
115+ </ div > #}
116+ </ section >
117+
118+ < hr >
119+
47120{# Resources #}
48121< section class ="container ">
49122 < h2 > Resources</ h2 >
@@ -108,27 +181,83 @@ <h2>{{group | capitalize}}</h2>
108181 </ article >
109182</ section >
110183
111- < hr >
184+ < script >
185+ ( function ( ) {
112186
113- {# Crates #}
187+ var element = document . querySelector ( "#crates" ) ;
188+ let tags = document . querySelectorAll ( ".filter-tag" ) ;
189+ var filter_element = document . querySelector ( ".filters" ) ;
190+ var filters = [ ] ;
191+ [ ] . forEach . call ( tags , function ( tag ) {
192+ filters . push ( tag . innerText )
193+ } ) ;
194+ // Dedup
195+ filters = [ ...new Set ( filters ) ] . sort ( ) ;
196+ enabled_filters = [ ]
114197
115- < section >
116- < h2 class ="container-full "> Rust Audio Crates</ h2 >
117- < div class ="crates ">
118- {% set crates = load_data(url=config.extra.repos_url, format="json") %}
119- {% for crate in crates | sort(attribute="updated_at") | reverse %}
120- < div class ="crate ">
121- < a target ="_blank " href ={{crate.svn_url}} >
122- < h5 >
123- < pre > {{ crate.name }}</ pre >
124- </ h5 >
125- </ a >
126- < div class ="details ">
127- < div class ="stars "> {{ crate.stargazers_count }} ☆</ div >
128- </ div >
129- </ div >
130- {% endfor %}
131- </ div >
132- </ section >
198+ function build_filters ( ) {
199+ filter_element . innerHTML = "" ;
200+ filters . forEach ( ( filter ) => {
201+ var filter_el = document . createElement ( "DIV" ) ;
202+ filter_el . classList . add ( "tag" ) ;
203+ filter_el . classList . add ( "filter-tag" ) ;
204+ filter_el . dataset . keyword = filter ;
205+ filter_el . innerText = filter ;
206+ filter_element . appendChild ( filter_el ) ;
207+ } ) ;
208+ }
209+
210+ function filter_entries ( ) {
211+ // Get all filterable elements
212+ let elements = document . querySelectorAll ( "#crates .crate" ) ;
213+ [ ] . forEach . call ( elements , function ( el ) {
214+ let keywords = el . dataset . keywords . split ( " " ) ;
215+ let is_active = keywords . some ( r => enabled_filters . indexOf ( r ) >= 0 ) ;
216+ if ( enabled_filters . length == 0 ) {
217+ el . style . display = "block" ;
218+ } else {
219+ if ( ! is_active ) {
220+ el . style . display = "none" ;
221+ } else {
222+ el . style . display = "block" ;
223+ }
224+ }
225+ } ) ;
226+ }
227+
228+ function toggle_filter ( keyword ) {
229+ let tags_with_keyword = document . querySelectorAll ( `[data-keyword="${ keyword } "]` ) ;
230+ let index = enabled_filters . indexOf ( keyword ) ;
231+ if ( index > - 1 ) {
232+ console . log ( "toggling off tag" ) ;
233+ // exists, toggle off
234+ enabled_filters . splice ( index , 1 ) ;
235+ [ ] . forEach . call ( tags_with_keyword , function ( el ) {
236+ el . classList . remove ( "toggled" ) ;
237+ } ) ;
238+ } else {
239+ console . log ( "toggling on tag" ) ;
240+ // doesn't yet exist, push
241+ enabled_filters . push ( keyword ) ;
242+ // toggle style for all tags
243+ [ ] . forEach . call ( tags_with_keyword , function ( el ) {
244+ el . classList . add ( "toggled" ) ;
245+ } ) ;
246+ }
247+ filter_entries ( ) ;
248+ }
249+
250+ build_filters ( ) ;
251+
252+ tags = document . querySelectorAll ( ".filter-tag" ) ;
253+ [ ] . forEach . call ( tags , function ( tag ) {
254+ tag . addEventListener ( "click" , ( ev ) => {
255+ let keyword = tag . innerText ;
256+ toggle_filter ( keyword ) ;
257+ } ) ;
258+ } ) ;
259+
260+ } ) ( ) ;
261+ </ script >
133262
134263{% endblock content %}
0 commit comments