From eae423048b3aa351d173c673fb8324e170c1fba1 Mon Sep 17 00:00:00 2001 From: Nilesh <19304+nileshtrivedi@users.noreply.github.com> Date: Thu, 2 Jun 2022 21:12:54 +0100 Subject: [PATCH 1/7] Hide treemap --- src/App.svelte | 4 ---- src/TopicList.svelte | 3 +++ static/map.html | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index 25817f5..173c0f9 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -97,10 +97,6 @@ - - - - diff --git a/src/TopicList.svelte b/src/TopicList.svelte index 6ad38f1..c4e7143 100644 --- a/src/TopicList.svelte +++ b/src/TopicList.svelte @@ -4,4 +4,7 @@ import SearchForm from "./SearchForm.svelte" +
+ Try mapview (beta) +
diff --git a/static/map.html b/static/map.html index 9394c40..1f2eb88 100644 --- a/static/map.html +++ b/static/map.html @@ -94,7 +94,7 @@ function hierarchy(topic_array, parent_id){ d3.json("/learn/topics.json?_shape=array&_size=5000", function(alltopics){ // console.log({alltopics}); var root = hierarchy(alltopics, ""); - console.log({root}); + // console.log({root}); initialize(root); accumulate(root); layout(root); From b5fa0899acc410162fbf53a96f278ffc00476e15 Mon Sep 17 00:00:00 2001 From: Nilesh <19304+nileshtrivedi@users.noreply.github.com> Date: Fri, 3 Jun 2022 11:39:27 +0100 Subject: [PATCH 2/7] TreeMap fixes --- README.md | 10 +++++----- db/README.md | 38 ++++++++++++++++++++++++++++++++++++++ package.json | 2 +- rollup.config.js | 2 +- static/map.html | 22 +++++++++++++++++++--- 5 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 db/README.md diff --git a/README.md b/README.md index 27c9726..933faaf 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ This is the exact same version. Your bookmarks will still be saved in localStora But if you'd like faster performance or to self-host this, say in your company's intranet, you need a general-purpose computer (that means Linux/Windows/Mac but not crippled OSes like Android or iOS) with Datasette (which is an exploratory tool for SQLite databases) installed. You can find [installation instructions specific to your operating system here](https://docs.datasette.io/en/stable/installation.html). -After cloning this git repository on your local machine, run `datasette . -o` in the top-level directory to start the datasette serve and open the app in your browser. +After cloning this git repository on your local machine, run `npm run start` in the top-level directory to start the datasette server and open the app in your browser. ## To contribute: @@ -26,7 +26,7 @@ This is a Wikipedia-scale project and we could use all kind of help: - To donate funds, [visit our OpenCollective](https://opencollective.com/learnawesome) - To report bugs, [create an issue](https://github.com/learn-awesome/learndb/issues) - To improve our topic taxonomy (improve sub-topics / prerequisites etc), [raise a PR on our Github with changes in `db/topics.csv` file](https://github.com/learn-awesome/learndb/tree/main/db) -- To improve the data about learning resources, [raise a PR on our Github with changes in `db/items.csv` file](https://github.com/learn-awesome/learndb/tree/main/db) +- To improve the data about learning resources, first read [db/README.md](db/README.md) and [raise a PR on our Github with changes in `db/items.csv` file](https://github.com/learn-awesome/learndb/tree/main/db) - To improve design and suggest features, [start a discussion](https://github.com/learn-awesome/learndb/discussions) - To fix technical bugs, [propose solutions on the issues](https://github.com/learn-awesome/learndb/issues) - For anything else, [start a discussion](https://github.com/learn-awesome/learndb/discussions) @@ -34,8 +34,7 @@ This is a Wikipedia-scale project and we could use all kind of help: ## To develop: When you modify the *.csv files in `db/`, you should re-generate the sqlite database with `./generatedb.sh`. -Run `npm run dev` to keep live-building the JS bundle as you edit the source code. -And then run `datasette . -o` to open the app in your browser. +Run `npm run dev` to keep live-building the JS bundle as you edit the source code. This automatically runs `datasette . -o` to open the app in your browser. You can install Datasette's Vercel plugin with: `datasette install datasette-publish-vercel`. To publish this, we first run `npm run build` followed by `npm run publish`. @@ -44,7 +43,8 @@ To publish this, we first run `npm run build` followed by `npm run publish`. The dataset here is identical to https://learnawesome.org/. But there are no user accounts, no social features like learning feeds or ActivityPub. Users' bookmarks are saved in browser's localStorage. -The source data is in `db/*.csv` files. This is imported into a sqlite database with `./generatedb.sh`. +The source data is in `db/*.csv` files. The schema is described in [db/README.md](db/README.md). +These CSV files get imported into a sqlite database with `./generatedb.sh`. We then rely on datasette to load this file and offer JSON APIs over HTTP. Settings and metadata are specified in `settings.json` and `metadata.json` which datasette uses. diff --git a/db/README.md b/db/README.md new file mode 100644 index 0000000..6c48cc9 --- /dev/null +++ b/db/README.md @@ -0,0 +1,38 @@ +# CSV format + +## topics.csv + +`name` is used as primary key and therefore, must be unique and avoid uppercase and special characters other than hyphen and slash. Here are some examples: `physics`, `linear-algebra`, `nations/india`, `programming-languages/objective-c`. + +`display_name` is used as human-readable name and can preserve uppercase. For eg: `ADHD`. + +`parent_id` should be the name of the parent topic. This makes it possible to show a hierarchical view. If a topic does not have `parent_id`, it would be at the top-level but if it doesn't have children topics of its own, it will be clubbed under a dummy top-level topic called `Misc`. + +`sort_index` is an integer that's used for controlling the ordering in which topics are displayed. + + +## items.csv + +`iid` should be a unique UUID. It is needed because `reviews.csv` needs to refer to items and there is no other natural primary key. Later, if we'd want to build collections of items, the same `iid` key would be helpful. + +`description` can contain markdown with multiple lines. + +`links` is an array value separated by `;`. Each item in this array a pair of `format` and `url` separated by `|`. For eg, `links` can have a value like this: `summary|https://sivers.org/book/Decisive;book|https://www.goodreads.com/book/show/15798078-decisive;summary|https://fourminutebooks.com/decisive-summary/`. + +We are considering including other fields like `ipfsHash` and `image` in each value of `links`. This decision is yet to be made. + +`topics` is a array value of topic names separated by `;`. These should exactly match `topics` table's `name` column. + +`creators` is arbitrary string for now. For eg: `Charles Darwin`. In future, this might become a full record on its own including fields like `name`,`website`,`twitter`,`email`. In that case, we will have to somehow figure out unique key for each creator that could serve the role of primary key and foreign key. + +`difficulty` must be empty or one of these: `childlike`, `beginner`, `intermediate`, `advanced`, `research`. + +`rating` is on a 5.0 point scale with up to two decimal places allowed. This is a curated value and should not be simply copied from external sources. + +`tags` can describe quality: `visual`, `entertaining`, `challenging`, `inspirational`, `interactive`. + +## reviews.csv + +`item_id` is a foreign key to `items.csv`. +`by` is the name of the person or item. +`blurb` is small description in markdown format. \ No newline at end of file diff --git a/package.json b/package.json index 4907c46..7e09da7 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "test": "echo \"Error: no test specified\" && exit 1", "build": "rollup -c", "dev": "rollup -c -w", - "start": "sirv public --no-clear", + "start": "datasette . -o", "publish": "datasette publish vercel learn.db --project learnawesome -m metadata.json --template-dir templates --static static:static --setting max_returned_rows 20000" }, "devDependencies": { diff --git a/rollup.config.js b/rollup.config.js index 04dd8a4..96b769b 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -20,7 +20,7 @@ function serve() { return { writeBundle() { if (server) return; - server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], { + server = require('child_process').spawn('npm', ['run', 'start'], { stdio: ['ignore', 'inherit', 'inherit'], shell: true }); diff --git a/static/map.html b/static/map.html index 1f2eb88..d7b4b39 100644 --- a/static/map.html +++ b/static/map.html @@ -21,7 +21,7 @@ body { } text { - pointer-events: none; + cursor: pointer; } .grandparent text { @@ -51,6 +51,16 @@ rect.parent, cursor: pointer; } +.leaf rect.parent { + cursor: pointer; + fill: #c9d9ff; +} + +.leaf rect.parent:hover { + cursor: pointer; + fill: #d9e9ff; +} + .children rect.parent { fill: #99F6E4; fill-opacity: .5; @@ -203,7 +213,11 @@ grandparent.append("text") .classed("children", true) .on("click", transition); - g.selectAll(".child") + g.filter(function(d) { return !d._children; }) + .classed("leaf", true) + .on("click",(n) => { window.parent.location.href = "/#/topic/" + n.name;}); + + g.filter(function(d) { return d._children; }).selectAll(".child") .data(function(d) { return d._children || [d]; }) .enter().append("rect") .attr("class", "child") @@ -217,6 +231,7 @@ grandparent.append("text") g.append("text") .attr("dy", ".75em") + .on("click", (n) => { window.parent.location.href = "/#/topic/" + n.name;}) .text(function(d) { return d.name.split('{')[0].split('(')[0] .split('[')[0]; }) .call(text); @@ -260,7 +275,8 @@ grandparent.append("text") function text(text) { text.attr("x", function(d) { return x(d.x) + 10; }) - .attr("y", function(d) { return y(d.y) + 10; }); + .attr("y", function(d) { return y(d.y) + 10; }) + .attr("text-decoration","underline"); } function rect(rect) { From 6913d4376c4bdbf97346f42d6e3e72a445304f10 Mon Sep 17 00:00:00 2001 From: Nilesh <19304+nileshtrivedi@users.noreply.github.com> Date: Fri, 3 Jun 2022 11:43:14 +0100 Subject: [PATCH 3/7] Attempting d3 loading issue fix --- static/map.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/map.html b/static/map.html index d7b4b39..17ad7f2 100644 --- a/static/map.html +++ b/static/map.html @@ -75,7 +75,7 @@ rect.parent,

- + - +

-
- + {#if !hideTopic} - { return {label: t.display_name, value: t.name}; }).sort((a,b) => a.label.localeCompare(b.label)).slice(0,10)} selected={null}/> + + {#each alltopics.sort((a,b) => a.display_name.localeCompare(b.display_name)) as topic} + {topic.display_name} + {/each} + {/if} - {#if !hideFormat} - - Any format - Books - Videos - Podcasts - - {/if} - - + Any tag Inspirational Educational @@ -49,6 +40,7 @@ Entertaining Visual Interactive + Open (no login or pay) @@ -60,15 +52,6 @@ Research - {#if !hideQuality} - - Any quality - Visual - Interactive - Entertaining - - {/if} - Sort by Rating diff --git a/src/TopicDetail.svelte b/src/TopicDetail.svelte index 5402965..f26d7f3 100644 --- a/src/TopicDetail.svelte +++ b/src/TopicDetail.svelte @@ -14,9 +14,8 @@ let query = { text: "", topic: "", - format: "", level: "", - tags: "", + tag: "", sortby: "rating" }; @@ -28,15 +27,14 @@ }); function handleQueryChanged(event){ - console.log("queryChanged: ", event.detail); + // console.log("queryChanged: ", event.detail); query = event.detail; } $: filteredItems = items.filter(item => { if(query.text && !item.name.toLowerCase().includes(query.text.toLowerCase())){ return false; } - if(query.format && !item.links.includes(query.format)) { return false; } if(query.level && item.difficulty != query.level){ return false; } - // TODO: apply tags filter + if(query.tag && !item.tags.includes(query.tag)){ return false; } return true; }).sort((a,b) => { if(query.sortby == 'rating') { return (a.rating - b.rating) }; diff --git a/src/TopicList.svelte b/src/TopicList.svelte index c4e7143..a95a910 100644 --- a/src/TopicList.svelte +++ b/src/TopicList.svelte @@ -5,6 +5,6 @@ diff --git a/src/TopicMasonryGrid.svelte b/src/TopicMasonryGrid.svelte index 5437bc4..f2c2f8d 100644 --- a/src/TopicMasonryGrid.svelte +++ b/src/TopicMasonryGrid.svelte @@ -84,7 +84,7 @@ -
+
{#each [...map.entries()].sort((t1,t2) => (t1[0].sort_index || 100) - (t2[0].sort_index || 100)) as parent}
diff --git a/src/tailwindui/ComboBox.svelte b/src/tailwindui/ComboBox.svelte index c9e4b06..82f627b 100644 --- a/src/tailwindui/ComboBox.svelte +++ b/src/tailwindui/ComboBox.svelte @@ -1,15 +1,24 @@ - - + + + + {#each filteredOptions as opt (opt.value)} - {opt.label} + {opt.label} {/each} diff --git a/static/map.html b/static/map.html index c6b3eb7..54bd042 100644 --- a/static/map.html +++ b/static/map.html @@ -23,6 +23,8 @@ body { text { cursor: pointer; + fill: #7a28cb; + } .grandparent text { @@ -40,11 +42,11 @@ rect.parent, } .grandparent rect { - fill: rgb(232, 255, 0); + fill: #f4b393; } .grandparent:hover rect { - fill: rgb(202, 225, 0); + fill: #f4d393; } .children rect.parent, @@ -54,21 +56,21 @@ rect.parent, .leaf rect.parent { cursor: pointer; - fill: #c9d9ff; + fill: #ffdbd1; } .leaf rect.parent:hover { cursor: pointer; - fill: #d9e9ff; + fill: #ffcfd4; } .children rect.parent { - fill: #99F6E4; + fill: #ceec97; fill-opacity: .5; } .children:hover rect.child { - fill: #D7CBFA; + fill: #deec97; } @@ -88,8 +90,8 @@ function hierarchy(topic_array, parent_id){ .map(item => ({ ...item, children: nest(items, item.name), value: 100 })) .map(item => { return item.children.length == 0 ? - {id: item.name, name: item.name.split("/").reverse()[0], value: 100} : - {id: item.name, name: item.name.split("/").reverse()[0], children: item.children} + {id: item.name, name: item.name, value: 100} : + {id: item.name, name: item.name, children: item.children} }); let topnodes = nest(topic_array, ''); // includes childless nodes @@ -98,7 +100,7 @@ function hierarchy(topic_array, parent_id){ let misc = {id: 'misc', name: 'Misc', children: topnodes.filter(t => t.value).slice(0,15)}; - return {name: "ยท", children: [...topnodes.filter(t => t.children), misc]}; + return {name: "", children: [...topnodes.filter(t => t.children), misc]}; } d3.json("/learn/topics.json?_shape=array&_size=5000", function(alltopics){ @@ -232,7 +234,7 @@ grandparent.append("text") g.append("text") .attr("dy", ".75em") .on("click", (n) => { window.parent.location.href = "/#/topic/" + n.name;}) - .text(function(d) { return d.name.split('{')[0].split('(')[0] + .text(function(d) { return d.name.split('/').reverse()[0].split('{')[0].split('(')[0] .split('[')[0]; }) .call(text); diff --git a/templates/index.html b/templates/index.html index 55dff58..125977c 100644 --- a/templates/index.html +++ b/templates/index.html @@ -46,6 +46,7 @@ + LearnAwesome From 8e78183e8e642f09fc840b872ea0efb57209118e Mon Sep 17 00:00:00 2001 From: Nilesh <19304+nileshtrivedi@users.noreply.github.com> Date: Fri, 3 Jun 2022 14:41:52 +0100 Subject: [PATCH 6/7] Added screenshots in README --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 933faaf..8879254 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,15 @@ In conjunction with this, we're also building an online game where this is prese [Visit https://learnawesome.vercel.app/](https://learnawesome.vercel.app/) -This is the exact same version. Your bookmarks will still be saved in localStorage so be assured that no personal data is being tracked or saved on this site. +image -But if you'd like faster performance or to self-host this, say in your company's intranet, you need a general-purpose computer (that means Linux/Windows/Mac but not crippled OSes like Android or iOS) with Datasette (which is an exploratory tool for SQLite databases) installed. You can find [installation instructions specific to your operating system here](https://docs.datasette.io/en/stable/installation.html). +image + +image + +Your bookmarks are saved in localStorage so be assured that no personal data is being tracked or saved on this site. + +But if you'd like faster performance or to self-host this, you need a general-purpose computer (that means Linux/Windows/Mac) with Datasette (which is an exploratory tool for SQLite databases) installed. You can find [installation instructions specific to your operating system here](https://docs.datasette.io/en/stable/installation.html). After cloning this git repository on your local machine, run `npm run start` in the top-level directory to start the datasette server and open the app in your browser. From 6ea5731bde50e824217db46286d26da8cf0bb2d6 Mon Sep 17 00:00:00 2001 From: Nilesh <19304+nileshtrivedi@users.noreply.github.com> Date: Fri, 3 Jun 2022 16:42:29 +0100 Subject: [PATCH 7/7] Remove datasette link --- src/App.svelte | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index 173c0f9..248a43c 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -123,11 +123,6 @@ - - - -

Datasette

-
\ No newline at end of file