MordOS - One OS to rule them all
git clone
the project locally
yarn install
to install all the dependencies
yarn start
to run the project in your browser
The client requested for a graphical user interface for a web based operating system. Considering that this is an MVP, functionality is supposed to be far from an OS but it does need to look and feel like an OS, to be appealing and fun to explore. Borgoth, being the imaginary flaming venture demon, should be this operating system's brand.
Client also requested functionalities that they thought might bring a lot of value, such as:
- Mord OS should support creating and managing plain text files and include a directory mechanic in order to sort the files as one wishes.
- There should be a simple authentication feature so not everyone can access the OS. A simple email and password flow will do for now. ( email: borgoth@mordos.com / pass: 12bindthem)
Other functionalities that are not as crucial but could really help enrich the OS:
- To keep up with all the news and banter going on, the OS could include a dedicated RSS reader app. (data source: https://jsonplaceholder.typicode.com/comments)
- Having a Camera app seems like a must for any OS today.
- It would be good if the OS had a Gallery app to view images from different sources without having to switch. (data source: https://jsonplaceholder.typicode.com/photos , but can include others)
- The OS could also have a dedicated web browser. Can be simple at first.
Creative freedom given as long as the following visual requirements are respected:
- The OS should look familiar to other systems so it doesnβt create confusion.
- No visual UI libraries should be used.
- Keep it sane :exploding_head:
Due to the client's requirement that Borgoth, an imaginary flaming venture demon, be the operating system's brand, I had to first find the appropriate assets to use ( drawings, photos ) e.g. logo, and it was critical that this asset be creative, fiery, and serious, as that was the style I was aiming for as an end-goal.
I had already decided that the entire OS would have a Ubuntu-ish look, and this image worked perfectly (it's worth noting that Photoshop had to be used in order to make a vector-based logo that would scale well quality-wise on different screen sizes, because the original source was a png with a solid background, so I had to remove the background and convert whole shape to svg).
I chose the colors orange/yellow/red and purple since they are the most representative of Borgoth ( a venturing flaming demon ) and Ubuntu.
Once I had logo and palette in place, I decided on a stellar system as a background, which perfectly complemented the already familiar look of Ubuntu ( due to the purple color ) and Borgoth's, who is described as a venturing demon, and what better place to venture out than a universe and it's stellar system π³οΈ?
The App bar was designed to look like the already-familiar Ubuntu style, with apps arranged vertically along the left edge of the screen. In order to make the entire user experience more user friendly, a hover effect with a tooltip should also be provided.
The App window should have a header with the app's icon and a 'X' (close window) icon. Because I, like Borgoth, am a great fan of dark themes,I decided that the section where the App's specific content will be rendered will have a dark background. π
That's pretty much it; everything else is basically little designer touches that are somewhat subjective to taste, such as fonts, input field styles and buttons, all of which can be found in sass files and code without me having to go into detail about them.
I'll try to keep this one short by simply giving a brief summary of the functionalities and how I implemented them; of course, the code is available for a more in-depth look. π
βββ public
β βββ favicon.ico
β βββ index.html
β βββ manifest.json
β βββ robots.txt
βββ README.md
βββ src
β βββ App.js
β βββ app.scss
β βββ assets
β β βββ cancel.svg
β β βββ fileDirectory.svg
β β βββ file.svg
β β βββ gallery.svg
β β βββ logo.svg
β β βββ rssFeed.svg
β β βββ textFile.svg
β β βββ ui-background.svg
β β βββ webBrowser.svg
β β βββ webcam.svg
β βββ components
β β βββ appbar
β β β βββ AppBar
β β β β βββ AppBar.js
β β β β βββ appbar.scss
β β β βββ Icon
β β β βββ Icon.js
β β β βββ icon.scss
β β βββ auth
β β β βββ Authentication.js
β β β βββ authentication.scss
β β βββ fileDirectory
β β β βββ Arrow
β β β β βββ Arrow.js
β β β βββ File
β β β β βββ File.js
β β β β βββ file.scss
β β β βββ FileDirectory
β β β βββ FileDirectory.js
β β β βββ fileDirectory.scss
β β βββ gallery
β β β βββ Gallery
β β β β βββ Gallery.js
β β β β βββ gallery.scss
β β β βββ Photo
β β β βββ Photo.js
β β β βββ photo.scss
β β βββ rssFeed
β β β βββ Comment
β β β β βββ Comment.js
β β β β βββ comment.scss
β β β βββ RssFeed
β β β βββ RssFeed.js
β β β βββ rssFeed.scss
β β βββ textFile
β β β βββ CreateModal
β β β β βββ CreateModal.js
β β β β βββ createModal.scss
β β β βββ CreateTextFile
β β β β βββ CreateTextFile.js
β β β β βββ createTextFile.scss
β β β βββ EditTextFile
β β β β βββ EditTextFile.js
β β β βββ HintOverlay
β β β βββ HintOverlay.js
β β β βββ hintOverlay.scss
β β βββ ui
β β β βββ Logo
β β β β βββ Logo.js
β β β β βββ logo.scss
β β β βββ UserInterface
β β β βββ UserInterface.js
β β β βββ userInterface.scss
β β βββ webBrowser
β β β βββ WebBrowser.js
β β β βββ webBrowser.scss
β β βββ webcam
β β β βββ Webcam.js
β β β βββ webcam.scss
β β βββ Window.js
β β βββ window.scss
β βββ constants
β β βββ appType.js
β β βββ sortType.js
β β βββ validCredentials.js
β βββ context
β β βββ AuthProvider.js
β β βββ TextFileProvider.js
β β βββ WindowProvider.js
β βββ hooks
β β βββ useFetch.js
β βββ includeMedia.scss
β βββ index.js
β βββ index.scss
β βββ utils
β βββ sortFiles.js
βββ yarn.lock
-
AuthProvider - Authentication context which wraps whole application and exposes auth state and functions.
-
WindowProvider - Window context which wraps whole UserInterface component and exposes window state and functions.
-
TextFileProvider - Text File context which wraps whole UserInterface component and exposes state and functions related to text files and it's management.
-
App - renders Authentication / UserInterface based on the isAuthenticated.
-
Authentication - responsible for holding the auth form and simple auth validation.
-
UserInterface - responsible for rendering individual Apps in
windowArea
( space on screen dedicated solely to the Apps window and it's content) based on the active status coming from WindowProvider. -
AppBar - responsible for triggering each Application's active status.
-
TextFile - responsible for text files Create / Update part of CRUD set of functionalities.
-
FileDirectory - responsible for text files Read / Delete part of CRUD set of functionalities.
-
WebCam - provides integration with your own webcam feed coming from your personal computer/phone.
-
WebBrowser - simulates a real web browser by allowing a user to see the content of requested url embedded inside of an iframe.
-
Window - reusable, serves as a wrapper around each app and provides it with themed styling while allowing customization.
- useFetch - receives an url as an argument, generic custom hook that can be used to retrieve data.
-
Drag & Move - window feature that allows user to drag and move App's window across the screen. It could be built by trying to register the mouse events such as
onMouseDown
,onMouseUp
&onMouseMove
of the ref element while keeping track of the current's mouse position coordinates on the screen. Certain limitations on the boundaries of the area that's allowed to be used, should also be set. -
"Priority" of windows - a feature that allows for windows to take priority based on the
selected
status. This feature could be implemented by dynamically assigningz-index
to a currentlyselected
window. -
File upload - a feature that let's user upload his own text file inside of
FileDirectory
component, could be accomplished by combining input field for file upload and Fetch Api / Axios library. -
Camera upload - a feature that let's a user take & save a picture taken with his webcam to
Gallery
component. -
More than one instance of same app running - currently, the OS is designed in a way which allows for a user to only activate one instance of the same App type. One of the potential improvements would be to allow for a user to edit more than one text file concurrently. But hey, this isn't a bug, it's a feature π
... and many more, but these would be some of the first ones that could be done in the next iteration of upgrades, when it comes to this specific MVP.
-
Saving user's credentials & session inside of localStorage - π€ This is a massive no-no. But this was done solely for the sake of convenience, to avoid accidental refreshes when exploring MordOS, and because Borgoth would be furious if he had to authenticate a user who had been authenticated just seconds before π. So this was only done to calm Borgoth's rage; otherwise, if we were talking about a production scenario with a real backend, this would surely be done through JWT.
-
Using my own media queries - If we're talking about optimizations, this would be one of the areas where we could make improvements. The one file
includeMedia.scss
is responsible for a large amount of the project's sass percentage, but on the other hand makes media queries much easier and intuitive. However, for such tiny projects as this one, it may be an overkill, especially if optimization is an issue. So, if it became necessary, I would definitely utilize my own media queries. -
Using an iframe as a solution for a dedicated web browser - iframes aren't really generous and they have their drawbacks, such as :
- Trying to embedded some sites, e.g. google, will result with
google.com refused to connnect
due to the google's own configuration which refuses to display it in a frame because it setX-Frame-Options
tosameorigin
.
- Trying to embedded some sites, e.g. google, will result with
The architecture was undoubtedly one of the aspects of the project that I had the most trouble with, and that required the most modifications and thought. At first, I was obsessed with creating the ideal, most reusable, most generic architecture in order to adhere to the DRY principle, but halfway through the project, I began to doubt my model owing to the unique requirements of each subsequent task. As a result of that unique requirement, the model had to be revised and slightly redesigned specifically to meet that requirement, casting doubt on the DRY principle and my architecture. And who knows, if this MVP continues to evolve, perhaps even more extensive remodeling will be required, thus coming up with the correct architecture design remains one of the most difficult challenges for me to solve. π
This project was a blast to work on. The client's creative flexibility was liberating, and it allowed me to demonstrate my ability to 'wear a different hat' depending on different tasks, ranging from graphics/ux design to web development, which is my passion. Borgoth was an ultra fun character to create story around, and even though the idea of implementing the functionalities of an operating system inside of a browser sounds really wild, I learned a lot with this project. Will definitely work with this client again, if the opportunity arises.