URL: https://vuedit.github.io/
- Make a .env file corresponding to
.env.example(You will need a provisioned Firebase Firestore database) - Run the following:
npm install
npm start
- You will need to build many Firestore indexes for searches
This project is basically a clone of reddit.com, offering a subset of core features available, such as making communities, posting, commenting, voting, etc.
The app is implemented in Vue (in case you couldn't guess) TypeScript, and utilises Firebase's client-side SDK to store data remotely, allowing for a static site.
- All users can:
- Browse posts on the homepage
- Go to a subview and browse the posts scoped to that subview
- Go to a user profile
- Go to a post and browse comments
- Search for posts starting with a phrase, on the home page and within a given subview (which is scoped to the subview posts)
- Sort by New, (default) Top, or Bottom
- Search by post title, or post body
- Users can sign up/log in using their Google account
-
All users can navigate to subviews and view posts and their comments
-
Authenticated users can:
- Create subviews from the home page (which are communities intended for specific types of posts)
- Subscribe/unsubscribe to communities (Join/leave button)
-
All users can view posts and any post comments from the home page or a subview page
-
Authenticated users can:
- Create posts under subviews
- Edit their posts
- Delete their posts
-
All users can view comments on post pages
-
Authenticated users can:
- Comment on posts
- Edit their comments
- Delete their comments
- Reply to other comments (to any depth)
- All users can view the score of a post/comment
- Authenticated users can upvote/downvote a post/comment
- Click on the arrow toggles the vote
- Clicking on the opposite arrow will also revoke the previous vote (if there was one)
- All users can toggle between a light and dark theme, which utilises Bootstrap's built-in dark theme classes.
- The theme preference persists between browser refreshes and sessions, as the preference is stored in a cookie.
- Defaults to the browser's dark theme preference
- All users can view user pages, which just lists the username
All content in user posts will be interpreted as markdown, allowing users to embed online imagery, tables, custom links, etc. in their posts. This was accomplished by using marked.js to convert markdown into HTML. Care was taken to prevent XSS attacks by sanitising the resulting HTML using DomPurify before rendering it.
If the user opts to just use plain text in the post, there is no difference in appearance.
Users can endlessly reply to comments, similarly to Reddit.
This was achieved using a recursive component, Comment, which will render any child comments specified in props as their own Comment component. The reply, edit, and delete comment events are manually bubbled up to the Post component, which handles them appropriately.
Firebase does not offer a way to search for substrings within fields, which is an intentional decision to ensure query performance.
Thus, the workaround was for searching to be only functional for the starting phrase (case-sensitive), achieved by using two query conditions, >= "[term]" and <= "[term] + \uf8ff". \uf8ff is a very high Unicode code point, thus this ensures that it will only match on strings that start with [term].