the-heap / emojions Goto Github PK
View Code? Open in Web Editor NEWEmbeddable Emoji Bar
Embeddable Emoji Bar
Hello! You made it to our RoadMap. That's awesome! Welcome. The Heap is happy you are here. Our roadmap is used to help us keep an eye on long running goals. I have broken the road map up into three separate steps — each corresponding to a different part of our code base.
For the most part, we will follow the road map step by step (stage 1, stage 2 etc), as I can only plan so much at a time — and often times in projects, things will change before you know it.
If you've read the README for this project then you should have a decent idea of what we're building. For those of you who prefer watching videos, I have also created an intro video on The Heap's youtube channel.
This project exists in three "Stages", each corresponding to a github milestone. Each stage will involve different kinds of code, and presumably, different challenges (many of which I have not anticipated). The following stages below link to their own respective roadmap.
We need to create an embeddable javascript snippet that a user can embed into their own website. The snippet's job is to find a way to create an emoji bar wherever the User (who installed the snippet) wants it to go.
If you are interested in contributing to the snippet or learning more: go to the Snippet Roadmap
The client is a small webapp that will exist to serve one primary function: allowing a user (someone who wants to embed an emojion bar on their site) to customize their emoji bar — choosing which emoji's show up.
This part of the project will be built with Elm, if we get to it. I'd like to build it with Elm to try something new, get better at functional programming, as well as attract other programmers with different perspectives / interests. Go checkout the roadmap
Notes: This part of the project has not been planned yet.
we will use JEST for writing unit tests. This requires the following
*.spec.js
for each js file in parallel?Use Editor Config to define a coding standard and prevent whitespace changes in git PR's between different developers.
Here's a possible config for our purposes:
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
[*.txt]
indent_style = tab
indent_size = 4
This issue requires that #7 be completed.
After someone has generated a style sheet to style our snippets, we can go ahead and actually style them!
Notes:
I would like to remind you our basic wireframe for this styling!
Read this to:
Figure out how to tackle the data fetching for the emojion bar from front end to back end.
I expect you to know:
Our general roadmap
Our API roadmap
EMOJION_ID
constantWe should have some kind of continuous integration so people can automatically run tests when pushing code.
Read this to:
Understand the road map for the emojion bar snippet
.
I expect you to know:
Our general roadmap
How we are architecting the snippet code
The Emojion bar snippet
is one component of three in this project. We need to create an embeddable javascript snippet that a user can embed into their own website. The snippet's job is to find a way to create an emoji bar wherever the User (who installed the snippet) wants it to go.
Here is a basic wireframe that we will be following:
We use a dummy example page to test the snippet on. It is at the root of the snippet
folder as example.html
.
The following steps are a general guideline (estimation, on my behalf) of how we might accomplish what we need to do. Each step has it's own issue (look for the number at the end of the line 👑)
We should definitely write some unit tests once we have jest ( #12 ) installed.
There will be some functions to make up for (that are not yet covered by tests) so we'll need to cover that ground.
Afterwards, let's encourage that we write tests for any function we write before submitting a PR.
This will be marked done once we have >90% coverage 😹
Here are the functions that are covered so far! This list is just _the test describe
blog ... there might be several little it
tests that could be written for functions if we're not covering _all of the functions...functionality!
Setup Elm in the client
folder.
Read this to:
What I expect you to know:
Background
Recently I worked on a project that made use of a "function pipe" to both organize and execute the entirety of a document's code. I had never come across this methodology before. Basically things worked by creating a long function pipeline that continuously passed a state
object down a pipe of functions.
Why is this interesting? Well, personally, I've always found it a bit tricky to figure out how to organize plain ol' javascript projects. Frameworks and libraries are great, especially in that they often recommend you organize your code to some (albeit, however small) standard. But we're not writing in a framework (happy to answer why that is if someone wants to know -- just create an issue).
Resources
This post helped me learn how to create a pipe function. Don't worry if that post confuses you — it's a fair bit to take in.
The goal here is to create a pipeline that will perform all the operations we need to go from nothing ... to something.
Implementation
I have already implemented an example of this in my first prototype of the snippet
, but it was not geared up for handling asynchronous actions (ie. fetching an emoji_count
from a database.
Here's a basic example
The pipe being declared:
function pipe (...fns) { return fns.reduce(
(f, g) => (...args) => g(f(...args))
)}
// note, this example is from the linked blog post. It is very terse, and not super clear what it's doing. When we write our pipe, it might start like this for the sake of making things easier to get moving, but it definitely needs better variable names (`f` and `g` are too unclear)
the pipe being invoked; and it's end result being called with a state
object
// --- Functions --- //
const render = pipe(
get_all_ids,
make_mounts,
populate_mount,
style_make_sheet,
add_click_event
)(state)
So if you look at the above code block, each parameter of the pipe
function is actually a "step" that our state goes through. If you're confused, don't worry! Let's humanize this a bit.
You have a sweet bike you want to fix up for summer time riding. You invite 5 friends over who are good at fixing bikes — each one of them has a real specialty.
James: Looks at your bike and says: "these tires need air!". He puts air in the tires. Then he passes the bike to Carly.
Carly: Looks at your bike and says: this bike needs a new chain. Good thing I have my chain breaking tool! She removes your old rusty chain and puts a new chain on and passes the bike off to Ren.
And the chain goes on. (ha, pun).
In this example, your friends are the FUNCTIONS
of the pipe. And your bicycle is the STATE
. Once your bike passes through the entire pipe you go from having a rusty piece of junk to a shiny new set of wheels. Sweet.
Nice. I think we're getting onto things now.
I'll be back to add more soon.
Goal: Find a way to mount the Emoji bar into the DOM.
User Interaction: For a user to add the Emojion Bar
to their site, they will have to do some coding to indicate where they want the emojion bar to mount. I suspect the best way to do this is to ask them to indicate this by adding a class or a unique id (or class, or data-attribute?) to the HTML element they would like the emojion bar to "mount" onto (or, below etc).
Approach: Likely, we will need the behaviour/functionality from our snippet:
Scanning the Dom
snippet
must be mounted at the bottom of the <body>
tag so it is aware of dom elementssnippet
will collect all id/classes/whatever identifier we use
on the page, and sort through ones that are intended for mounting the emojion bar:<div id="emojion_mount_22432ai2bj" class="callout">
Mounting the Emojion Bar
Possible Issues:
.classes
. Maybe a data-attribute? ie:<div id="mycoolDiv" data-emojion="mount_hash23849rfa"> ... </div>
Our state object is going to be passed down from function to function in our function pipe (see #3 if unfamiliar.
Our state will probably look something like this:
var state = {
emojis : {},
dom : { mounts: [], containers: []},
}
There are two main pieces of "state" in our snippet:
This is our data — eventually will live in a database, and we will get / send it with network requests
At the lowest level - this is just a UI - a visual display of our data.
Somehow we connect the two - and for now we won't worry about how network requests would come in (ie. getting this data form a database or sending it to one). For now we just want the following to happen: click an emoji and update the state, whenever the state updates, re render the dom elements.
/Here's some pseudo code for what we'll want to do:
When I open up the dev tools and click on an emoji button, I see the contents of every emoji bar being rerendered instead of just the contents of the emoji button that was clicked on.
A related issue is that event listeners are never being removed (see incrementEmojiCount
function). So if an emoji bar is rerendered, new buttons with new event listeners are being added to the DOM. I'm not sure what effect this may have (or whether it's necessarily a problem) but seems fishy.
add an event listener to the emoji bar itself then allow button clicks to bubble up?
Read this to:
Brainstorm / Think about how to setup flask.
I expect you to know:
We'll need an example site for loading the snippet into for testing.
Intent:
Our snippet must communicate with an api at some point, to achieve it's full functionality. Let's template out some code that will eventually achieve this if / when we get a server.
What you should know:
We'll need to set up some functions in our pipeline to perform two basic HTTP requests: GET
and POST
.
Somewhere near the beginning of our function pipe we will be making an HTTP request to get the emojion bars for the current user's site.
Somewhere else we'll need to set up a function that is set to fire whenever a user clicks on an emoji to fire it off.
We need to make our function pipe be able to do things asynchronously; at some point in time we want this snippet to make a network call — an asychronous action.
Currently, our function pipe executions every function one after another, and will not launch another function until it has completed the execution context of the current function.
How can we make the pipe
function handle taking functions that perform asynchronously?
Backend:
FrontEnd
Footnotes
the structure of the returned data should probably be structured similarly to how it looks in the front end currently. Also, we'll have to make sure that the mounting point strings (ie. where a user would want to mount the emojion bar) corresponds to the data structure coming from the back end.
If a user's mounting points aren't in the back end, it should create a record that corresponds to it; but this all needs to be unique to the user.
Get the basic scaffolding of a single page app built with elm.
Even though I have read the contribution guidelines, I continually forget the main points I need to hit. I think this would help build some consistency.
Read this to:
Help out with setting up styling the emojion bar
I expect you to know:
how we are architecting the data flow in this app. Please read #3
Just like our snippet itself is added to the DOM by a user, we need the snippet to create a stylesheet that styles the classnames of our emojion bar. A <style>
tag is quite similar to a <div>
or a <span
> in that they can both be created using javascript.
To do this, here are a few hints:
pipe
functionmakeContainers
function.If this issue appeals to you, please assign it to yourself and comment to let others know you want to work on it.
Currently our pipe
function looks something like this:
/**
* create a function pipe.
* TODO: refactor to be more readable. PLEASE.
* @param {functions} funs -> unknown number of functions
* @returns - a state object.
*/
function pipe(...funs) {
return funs.reduce(
(f, g) => (...args) => g(f(...args))
)
}
This is super, not-readable (to me). I mostly ripped it straight from this blog. (bad form! copy pasting code!)
The new function should try and be more explicit — with names that are more relevant to .reduce
(no using f, g
.)
This snippet/example.html
looks like its been borrowed from somewhere, its also pretty daunting as someone just joining the project. Lets simplify the page and highlight a common use case for Emojions while we're at it.
I propose that we have a simple article comments section as a common use case (we can build out more examples later, and possibly in the client?)
The objective here is to make the example.html
dead simple.
This is for the snippet section.
Having hard-set versions for dependencies can allow for better long-term stability. I think we should move to using absolute versions only:
"devDependencies": {
"husky": "^0.13.3",
"lint-staged": "^3.4.0",
"prettier": "^1.2.2"
}
To:
"devDependencies": {
"husky": "0.13.3",
"lint-staged": "3.4.0",
"prettier": "1.2.2"
}
This is probably a bad idea since it makes things extremely manual. However, a service exists that can integrate with GitHub that will manually update and manage dependency upgrades. Doppins will give us the flexibility of version ranges but with the stability of pinned versions.
The workflow would be:
This has already saved me twice in three weeks due to some crazy breaking React Updates.
Today, we have to add <element id="emojions_someuniquestring">
for each area we want to add Emojions to. This seems a bit unnecessary, we probably want to search for .emojions
or something to that effect as a class name rather than a unique ID.
Any thoughts on this @qazqwezxc ? I have more experience with sqlalcehmy with flask than any nosql choices, but I'm open to whatever! Ideally whatever we choose is simple and not too hard to set up and document.
Read this to:
Understand the road map for the emojion bar Emoji Picker
I expect you to know:
snippet
doesThe client is a small webapp that will exist to serve one primary function: allowing a user (someone who wants to embed an emojion bar on their site) to customize their emoji bar — choosing which emoji's show up.
This part of the project will be built with Elm, if we get to it. I'd like to build it with Elm to try something new, get better at functional programming, as well as attract other programmers with different perspectives / interests.
Here is a basic wireframe that we will be following:
TODO
The following steps are a general guideline (estimation, on my behalf) of how we might accomplish what we need to do. Each step has it's own issue (look for the number at the end of the line 👑)
Read this to:
Understand the road map for the emojion bar api
.
I expect you to know:
Our general roadmap
How we are architecting the snippet code
The API is sort of the final puzzle piece to finish the snippet. Without an API anybody can still use our Snippet; but it's a byodb
- bring your own database` - they need to hook up the snippet to whatever their database system is.
If we want to provide full ease of use; it would be idea to provide a back end api that stores and retrieves emoji counts per user.
client
app and picks out some emojis they want to fill for their own personal emoji bar.client
app will allow a user to specific the endpoint for their emojion bars to be saved to and retrieved from -- this is the url for an instance of this custom api.The following steps are a general guideline (estimation, on my behalf) of how we might accomplish what we need to do. Each step has it's own issue (look for the number at the end of the line 👑)
Let me know if I've correctly or incorrectly opened an issue btw.
Backend:
Frontend:
Example of mockdata here:
Unique values will based off of it's "id" value
Read This to:
What I expect you to know / have done:
I could use your feedback. Help me make the next The Heap project easier to get started and more fun. Feel free to post any thoughts here; if nothing comes to mind immediately here are some prompts:
Tagging all you lovely contributors for your thoughts. @ericbastarache @mihok @hyperwidget @broneks @gilbertkennen @ChristofLee
We should use all contributors To recognize the hard work of our contributors!
When an emoji is clicked, it increments the number and also adjusts the width of the button. Flexbox tries to accommodate this and adjusts the width.
This is caused by flexbox
and was introduced with adaptive styling #37.
May require padding or a min-width on the content of .emojion__single
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.