hackerexperience / heborn Goto Github PK
View Code? Open in Web Editor NEWLicense: GNU Affero General Public License v3.0
License: GNU Affero General Public License v3.0
We can heavily cache both app-[hash].{js,css}, but index.html should always be fetched from origin, so it returns a new hash in case app.js/css has changed. Index.html is quite small anyway, it represents less than 1% of the total page size.
Not sure if it's being cached by nginx or cloudflare or both.
Implement design based on mockup from #34
Steps to replicate:
Right click on any window (with context menu support). The context menu will be far from the mouse. That's likely an css issue (on the landing page, if you right click on the sign-up component, it will work correctly). Another example of right click working correctly is this demo.
We're currently using a import/expose convention that looks like that:
module OS.Messages exposing (OSMsg(..))
import OS.WindowManager.Messages
type OSMsg
= MsgWM OS.WindowManager.Messages.WMMsg
I propose changing it into that:
module OS.Messages exposing (Msg(..))
import OS.WindowManager.Messages as WM
type Msg
= WMMsg WM.Msg
*.Messages
, *.Models
, *.Subscriptions
, *.Update
and *.View
are parts of the same *
, I believe that they were split to make things easier on eyes and to reduce compiler stress when changing minor things, so it may make some sense to join them when accessing from the outside.
Elm allows importing multiple modules under the same alias, and it will trigger warnings on name collisions, but this is not even a problem because:
Messages
just exposes Msg types;Subscriptions
just exposes one function;Update
just exposes one function;View
may expose many functions, but usually just view
, additional functions could get a "view" prefix to avoid collisions;Another thing is that this change reduces some cognitive load.
A recent PR (PR #131) changed how login and logout works (to make the UI less optimistic), the changes were:
But it looks like that the production connection is too unstable, so the game logs out after 10 seconds of connection.
I'll try to make it more fault tolerant but I really believe that the connection is too unstable, this should be further investigated.
(this problem couldn't be tested locally, local websocket connections are too stable)
(edit: turns out that this is a balancer misconfiguration)
Seriously
GameModel
or...Game
should affect Apps
I've found a problem while designing/planning the models of the DesktopManager
(aka Workspaces
), I'll try to be as didactic as possible now...
As of #103, we forbid Game -> App
communication, right? Tons of advantages, simplifies things a lot and etc but...
There's no way to reliably update an
App
model
after updating theGame
model
.
<assumptions>
Ideally, we want to update
our Apps
model
after changing the Game
model
.
</assumptions>
To make this happen, we have to do this flux:
every GameModel.update
calls Apps.update
It's not possible to do this flow right now for two main reasons:
GameUpdate
and pass it forward to the Apps
, so using message based solutions requires adding tons of boilerplate. 😞App
function to sync apps with the GameModel
.There is three main solutions for that:
GameUpdateMsg
to each App
model.
Game
model
.App
(and also OS
).GameModel
without any message.
API
function, more boilerplate on Apps
.App
model
update
based on GameModel
, removing GameModel
param from Apps
update
function
Apps
will just contain UI
state. (separation of concerns)Game
.Obviously I'm a fan of the 3rd solution 😄 , but it might be the wrong solution for us, it's too much opinionated. (actually the 3rd solution introduces heavy overhead unless we use an app cache system within Game, so I'm not liking this solution anymore)
Note: Maybe this whole issue is no surprise, maybe we don't want to keep any state references to
anything onGameModel
, but these are just assumptions, I'm not sure of anything.
The most important to think is: What we decide now will change how we design every App
models
.
NOTE: Everyone is assigned for discussion, but I'll be the one who will fix it
Title says it all. This depends on integrating the repository to a CI server.
Steps to replicate:
Open multiple windows (at least two) of any type. Move the first one around.
It should:
Implement design based on mockup from #40
Funny this happened after 5 or 6 long builds, so probably passed some 600 tests until it found this one 😲
[Test] Running 39 tests. To reproduce these results, run: elm-test --seed 486670792
[Test]
[Test] ��� heborn
[Test] ��� filesystem
[Test] ��� file operations
[Test] ��� delete files
[Test] ��� delete folder
[Test] ��� folder path no longer exists
[Test]
[Test] Given 1389533003
[Test]
[Test] True
[Test] ���
[Test] ��� Expect.equal
[Test] ���
[Test] False
from this build
On the main 1.hackerexperience.com portal the login button no longer does anything
These problems gave birth to one pretty powerful feature: session management (aka workspaces / virtual desktops).
But they won't work like everyday virtual desktops, cause they're not virtual desktops of a single computer, but of many.
App
Window
allows you to control a Server
;Servers
running at same time;Gateway
and Endpoint
are window contexts;Gateway
, that represents your owned Server
;Endpoint
, that represents the server you're invading;Gateway
windows allows you to control your servers, Endpoint
windows allows you to control invaded servers. (there are some windows without context, those won't allow endpoint controlling).Our requirements are easy to understand, but hard to implement with simple solutions:
There are some solutions already discussed, but they are confusing:
Gateway
and Endpoint
to IP/aliases
Context
is confusingDesktop
gets bloated easilyWindow
with invalid state
While this is not the best solution, it's the one that works with our current backend:
Unreachable
window content until state gets valid again.Looks like that opening multiple windows moves them around.
On a newly opened tab:
This is a side-effect of #107. Solving it is required before solving this one.
Before 1b4806b, Core used to subscribe all apps using a MsgApp
. Now, apps subscriptions are waiting their own model and their subscriptions are broken.
FYI: The only subscription we are using in apps right now is the one which propagates ContextMenu events (like closing it).
I would like to start by saying that I was able to successfully migrate and login to HEBorn. It has a very good design. But there are some bugs:
Right now, if i login and then logout, the login form will still have my original input (including my password)
What we already have:
Okay
UnknownModel
)Tasks :
{ browser: WindowId, tab: Int }
Browser
to Tab
Endpoint.member
in A.B.Pages.Default.View
to hide password fieldI've tested on chrome and firefox, there are no message like wrong password/username.
With the addition of Context (local or remote) with #52, we need to replace all previous Context
entries with Menu
to make sure it does not get confusing.
It is possible to click the app icons on the dock to spawn 32 windows of the same kind.
However these redundant windows are unnecessary since most windows will be having only 2 contexts (local, remote).
I suggest limiting allowed windows for any application to no more than 2. This can prevent unintended chaos on the UI.
While adding new channels/ws requests, it got to my attention that we're breaking some core rules of the elm:
One of the core rules of The Elm Architecture is never put functions in your Model or Msg types.
It may cost a little bit of extra code to model everything as data, but the architecture and debugging
benefits are worth it. - evancz
We're breaking this rule by allowing ResponseDecoder
s on our Core.Msg
type.
While it doesn't do anything too bad right now (aside from blocking the export/import history feature of the time travelling debugger), it will make our life harder in the near future as elm doesn't stringfy functions, making it impossible to inspect their content properly while debugging Msgs.
Also, I believe that there's plenty room for reducing boilerplate from our codebase (or at least better organizing for scale... Requests.Models
I'm looking at you).
EDIT: another problem found, we're using messages as commands on both Core
& Requests
Initial implementation here
I'm introducing Maybe Response
to avoid having tons of NoOps types over the code.
Before doing that we were using a Debug.crash
to cast Result a b
to b
, to avoid having to deal with Results/Maybes on */Update.elm
...
This had a good reason on that time, but now (with the new structure for Updates) the cost of handling maybes is fairly low.
The advantages of crashing are that it's impossible to play the game with an outdated client, but crashing is makes the game unresponsible. It would be better to introduce a "blocking modal" asking the player to refresh the window.
I'm proposing to replace the Debug.crash with a Result.toMaybe
-like function (that will still report errors without crashing).
Minimize window works similarly to maximize, with the difference that we may have to render multiple minimized windows while only one maximized window can be rendered at a time.
This is how I see window minimize working:
1 - Player clicks on minimize button from an open window, it goes to the icon dock.
2 - On the icon dock, every minimized window is displayed as a dot (or light) below its application icon. Similar to mac os.
3 - Once the player clicks on the icon (with minimized window), the window becomes visible again at the position it was before.
It's all easy and stuff, but here are some edge cases that makes this trickier:
My opinion on this ( @mememori happy to hear yours too):
What we already have:
OS.Header.Notifications
Tasks:
Create model
Dict Id { content: Union, action: Union, time: Time, read: Bool }
filterUnreaded
countUnreaded
hasUnreaded
read id
getOrdered
Apply this type to:
Discard OS.Header.Notifications
Adapt OS.Header.View
Create toast viewing as OS.Toast
{ toShow : (id: NotificationId, until: Time) }
Notifications bootstrap
Notifications .Updates
New notification event
Files that need to change:
src/Apps/Explorer/Models.elm
src/Apps/LogViewer/Models.elm
src/Game/Account/Models.elm
src/Game/Servers/Models.elm
src/OS/WindowManager/Models.elm
This issue is mostly deferred until #84 is merged.
Build, test and release automatically. Improves overall project quality and confidence, as well as enabling us to iterate quickly. CD makes a dozen of releases per day become boring.
The separation between the window header and the window body contains one extra pixel that makes the blue background visible in a very thin line between the header and the body. Do you see it?
(Fancy wording for Login)
So, here's an idea to make our dev flow easier.
Currently each object from the View, like any log entry or file entry, is hard-coded into the view itself. Try to abstract the act of loading the object from rendering (styling) it.
Example:
Instead of
[ div [ class [ CntListEntry, EntryDir ] ]
[ span [ class [ DirIcon ] ] []
, span [] [ text "Downloads" ]
]
, div [ class [ CntListEntry, EntryArchive ] ]
[ span [ class [ VirusIcon ] ] []
, span [] [ text "MyVirus.spam" ]
, span [] [ text "2.3" ]
, span [] [ text "230 MB" ]
]
, div [ class [ CntListContainer ] ]
[ div [ class [ CntListEntry, EntryArchive ] ]
[ span [ class [ FirewallIcon ] ] []
, span [] [ text "TheWall.fwl" ]
, span [] [ text "4.0" ]
, span [] [ text "230 MB" ]
]
, div [ class [ CntListChilds ] ]
[ div []
[ span [ class [ ActiveIcon ] ] []
, span [] [ text "Active" ]
, span [] [ text "4.5" ]
, span [] []
]
, div []
[ span [ class [ PassiveIcon ] ] []
, span [] [ text "Passive" ]
, span [] [ text "3.5" ]
, span [] []
]
]
]
]
use something like
loadFiles model =
-- files = (getFilesOnPath model)
files = [file1, file2, file3]
List.map renderFile files
renderFile file =
div [ class [ CntListEntry, EntryArchive ] ]
[ span [ class [ file.icon ] ]
, span [] [ text file.name ]
]
viewExplorerMain model =
renderHeader model
renderEntries model
renderEntries model =
div [ class [ ContentList ] ]
[ loadFiles ]
l
Above code is wrong, but it's OK to get an idea of what I mean. In simpler words, make the View code generic.
The List.map renderFiles files
is just a suggestion, you don't have to do exactly like this. Though it seems like the way to go. Probably the best way to get files on path is to use Filesystem's function getFilesOnPath
.
By default your filesystem is empty, so if you want to add some dummy data, all you have to do is replace the original files
list with myMadeupFiles
or something like that.
I'm open to suggestions on how to improve this "pattern".
Hello @renatomassaro.
Today, each Jenkins builds took almost 3m and 40s to finish. Sometimes we have to merge more than one PR ready to merge, and because of jenkins after merging one we have to wait before merging the next.
I think we can improve Jenkins in two-ways:
Cache npm-modules
It takes too much time to install modules, and it sometimes it randomly fails.
We could use a solution like this: Speeding Up NPM Installs, saving our tar in $JENKINS_HOME
(We should also cache, in a separate tar, our submodules...)
Change ('Lint', 'Test', 'Compile') from parallel to serial tasks
We all know how painful is to run multiple instances of elm simultaneously. Poor jenkins farm...
Lint and tests fails much earlier than compiling would. This would reduce resources usage.
:: OFF-TOPIC:: Is jenkins building PRs for any github member? Can one add a PR with a modified Makefile that will run crazy shell commands?
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.