Skip to content

Commit

Permalink
Implement progressbar on top of game tile
Browse files Browse the repository at this point in the history
Major rework of the types was necessary to achieve this.
But I think this simplified the model a bit which could speed up further developments.

Also fixed the problem, that an old aborted download messed up the progress bar.
  • Loading branch information
NicoVIII committed Apr 17, 2022
1 parent fbd42d9 commit 3a3ef65
Show file tree
Hide file tree
Showing 18 changed files with 339 additions and 310 deletions.
3 changes: 2 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-dotnettools.csharp",
"ionide.ionide-fsharp",
"editorconfig.editorconfig",
"ybaumes.highlight-trailing-white-spaces",
"aaron-bond.better-comments",
"gruntfuggly.todo-tree",
"cschleiden.vscode-github-actions",
"GitHub.copilot",
"ionide.ionide-fsharp",
],
// "runArgs": [],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
Expand Down
2 changes: 1 addition & 1 deletion paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ NUGET
NicoVIII.GogApi (3.0)
FsHttp (>= 6.0.1)
NicoVIII.FSharp.Json (>= 0.5)
NicoVIII.SimpleOptics (0.1)
NicoVIII.SimpleOptics (0.2)
FSharp.Core (>= 6.0)
runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3)
Expand Down
33 changes: 8 additions & 25 deletions src/Andromeda/AvaloniaApp/DomainTypes.fs
Original file line number Diff line number Diff line change
@@ -1,32 +1,15 @@
namespace Andromeda.AvaloniaApp

open Andromeda.Core.DomainTypes
open Avalonia.FuncUI.Components.Hosts
open GogApi.DomainTypes
open System

[<AutoOpen>]
module DomainTypes =
type DownloadStatus =
{ gameId: ProductId
gameTitle: string
filePath: string
fileSize: float
installing: bool
downloaded: int }

module DownloadStatus =
let create id gameTitle filePath fileSize =
{ DownloadStatus.gameId = id
gameTitle = gameTitle
filePath = filePath
fileSize = fileSize
downloaded = 0
installing = false }

let gameToDownloadInfo (game: InstalledGame) =
{ ProductInfo.id = game.id
title = game.name }
module Game =
open GogApi.DomainTypes
open Andromeda.Core.DomainTypes

let toProductInfo game : ProductInfo = { id = game.id; title = game.name }

open Avalonia.FuncUI.Components.Hosts
open System

type IAndromedaWindow =
abstract Close: unit -> unit
Expand Down
60 changes: 42 additions & 18 deletions src/Andromeda/AvaloniaApp/Icons.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,46 @@ open Avalonia.Controls
open Avalonia.Controls.Shapes
open Avalonia.FuncUI.DSL

module Icons =
let settings =
module Icon =
module PathData =
// From https://materialdesignicons.com/icon/cog-outline
Canvas.create
[ Canvas.width 24.0
Canvas.height 24.0
Canvas.classes [ "icon" ]
Canvas.children
[ Path.create
[ Path.data
"M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12A2,2 0 0,0 12,10M10,\
22C9.75,22 9.54,21.82 9.5,21.58L9.13,18.93C8.5,18.68 7.96,18.34 7.44,17.94L4.95,18.95C4.73,19.03 4.46,18.95 4.34,18.73L2.34,15.27C2.21,15.05 2.27,\
14.78 2.46,14.63L4.57,12.97L4.5,12L4.57,11L2.46,9.37C2.27,9.22 2.21,8.95 2.34,8.73L4.34,5.27C4.46,5.05 4.73,4.96 4.95,5.05L7.44,6.05C7.96,5.66 8.5,\
5.32 9.13,5.07L9.5,2.42C9.54,2.18 9.75,2 10,2H14C14.25,2 14.46,2.18 14.5,2.42L14.87,5.07C15.5,5.32 16.04,5.66 16.56,6.05L19.05,5.05C19.27,4.96 19.54,\
5.05 19.66,5.27L21.66,8.73C21.79,8.95 21.73,9.22 21.54,9.37L19.43,11L19.5,12L19.43,13L21.54,14.63C21.73,14.78 21.79,15.05 21.66,15.27L19.66,18.73C19.54,\
18.95 19.27,19.04 19.05,18.95L16.56,17.95C16.04,18.34 15.5,18.68 14.87,18.93L14.5,21.58C14.46,21.82 14.25,22 14,22H10M11.25,4L10.88,6.61C9.68,6.86 8.62,\
7.5 7.85,8.39L5.44,7.35L4.69,8.65L6.8,10.2C6.4,11.37 6.4,12.64 6.8,13.8L4.68,15.36L5.43,16.66L7.86,15.62C8.63,16.5 9.68,17.14 10.87,17.38L11.24,\
20H12.76L13.13,17.39C14.32,17.14 15.37,16.5 16.14,15.62L18.57,16.66L19.32,15.36L17.2,13.81C17.6,12.64 17.6,11.37 17.2,10.2L19.31,8.65L18.56,\
7.35L16.15,8.39C15.38,7.5 14.32,6.86 13.12,6.62L12.75,4H11.25Z" ] ] ]
let cogOutline =
"M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14"
+ "A2,2 0 0,0 14,12A2,2 0 0,0 12,10M10,22C9.75,22 9.54,21.82 9.5,21.58L9.13,18.93"
+ "C8.5,18.68 7.96,18.34 7.44,17.94L4.95,18.95C4.73,19.03 4.46,18.95 4.34,18.73L2.34,15.27"
+ "C2.21,15.05 2.27,14.78 2.46,14.63L4.57,12.97L4.5,12L4.57,11L2.46,9.37C2.27,9.22 2.21,8.95 2.34,8.73"
+ "L4.34,5.27C4.46,5.05 4.73,4.96 4.95,5.05L7.44,6.05C7.96,5.66 8.5,5.32 9.13,5.07L9.5,2.42"
+ "C9.54,2.18 9.75,2 10,2H14C14.25,2 14.46,2.18 14.5,2.42L14.87,5.07C15.5,5.32 16.04,5.66 16.56,6.05"
+ "L19.05,5.05C19.27,4.96 19.54,5.05 19.66,5.27L21.66,8.73C21.79,8.95 21.73,9.22 21.54,9.37L19.43,11"
+ "L19.5,12L19.43,13L21.54,14.63C21.73,14.78 21.79,15.05 21.66,15.27L19.66,18.73"
+ "C19.54,18.95 19.27,19.04 19.05,18.95L16.56,17.95C16.04,18.34 15.5,18.68 14.87,18.93L14.5,21.58"
+ "C14.46,21.82 14.25,22 14,22H10M11.25,4L10.88,6.61C9.68,6.86 8.62,7.5 7.85,8.39L5.44,7.35L4.69,8.65"
+ "L6.8,10.2C6.4,11.37 6.4,12.64 6.8,13.8L4.68,15.36L5.43,16.66L7.86,15.62C8.63,16.5 9.68,17.14 10.87,17.38"
+ "L11.24,20H12.76L13.13,17.39C14.32,17.14 15.37,16.5 16.14,15.62L18.57,16.66L19.32,15.36L17.2,13.81"
+ "C17.6,12.64 17.6,11.37 17.2,10.2L19.31,8.65L18.56,7.35L16.15,8.39C15.38,7.5 14.32,6.86 13.12,6.62"
+ "L12.75,4H11.25Z"

// https://materialdesignicons.com/icon/update
let update =
"M21,10.12H14.22L16.96,7.3C14.23,4.6 9.81,4.5 7.08,7.2C4.35,9.91 4.35,14.28 7.08,17"
+ "C9.81,19.7 14.23,19.7 16.96,17C18.32,15.65 19,14.08 19,12.1H21C21,14.08 20.12,16.65 18.36,18.39"
+ "C14.85,21.87 9.15,21.87 5.64,18.39C2.14,14.92 2.11,9.28 5.62,5.81C9.13,2.34 14.76,2.34 18.27,5.81L21,3"
+ "V10.12M12.5,8V12.25L16,14.33L15.28,15.54L11,13V8H12.5Z"

let create pathData =
Canvas.create [
Canvas.width 24.0
Canvas.height 24.0
Canvas.classes [ "icon" ]
Canvas.children [
Path.create [
Path.data (pathData: string)
]
]
]

let settings = create PathData.cogOutline

let noUpdate =
let pathData = PathData.update + "M0,0L24,24"
create pathData
5 changes: 1 addition & 4 deletions src/Andromeda/AvaloniaApp/Init.fs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
namespace Andromeda.AvaloniaApp

open Andromeda.Core
open Andromeda.Core.DomainTypes
open Elmish
open GogApi.DomainTypes

open Andromeda.AvaloniaApp.Components

Expand All @@ -17,8 +15,7 @@ module Init =
let state =
Authenticated
{ authentication = authentication
downloads = Map.empty
installedGames = Map.empty
games = Map.empty
notifications = []
settings = settings
terminalOutput = []
Expand Down
16 changes: 12 additions & 4 deletions src/Andromeda/AvaloniaApp/Model.Optics.fs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
namespace Andromeda.AvaloniaApp

open SimpleOptics
open SimpleOptics.Presets

open Andromeda.Core.DomainTypes

/// Optics to simplify usage of state
module MainStateOptic =
// Base lenses
let authentication =
Lens((fun r -> r.authentication), (fun r v -> { r with authentication = v }))

let downloads = Lens((fun r -> r.downloads), (fun r v -> { r with downloads = v }))

let installedGames =
Lens((fun r -> r.installedGames), (fun r v -> { r with installedGames = v }))
let games = Lens((fun r -> r.games), (fun r v -> { r with games = v }))

let notifications =
Lens((fun r -> r.notifications), (fun r v -> { r with notifications = v }))
Expand All @@ -19,3 +20,10 @@ module MainStateOptic =

let terminalOutput =
Lens((fun r -> r.terminalOutput), (fun r v -> { r with terminalOutput = v }))

// Composed lenses
let game productId =
Optic.compose games (MapOptic.find productId)

let gameStatus productId =
Optic.compose (game productId) (GameOptic.status)
4 changes: 1 addition & 3 deletions src/Andromeda/AvaloniaApp/Model.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ namespace Andromeda.AvaloniaApp
open Andromeda.Core.DomainTypes
open GogApi.DomainTypes

open Andromeda.AvaloniaApp
open Andromeda.AvaloniaApp.Components

/// Special contexts the application can be in which possibly handle their own
Expand All @@ -15,8 +14,7 @@ type Context =

type AuthenticatedState =
{ authentication: Authentication
downloads: Map<ProductId, DownloadStatus>
installedGames: Map<ProductId, InstalledGame>
games: Map<ProductId, Game>
notifications: string list
settings: Settings
terminalOutput: string list
Expand Down
14 changes: 8 additions & 6 deletions src/Andromeda/AvaloniaApp/Msg.fs
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
namespace Andromeda.AvaloniaApp

open Andromeda.Core.DomainTypes
open GogApi.DomainTypes

open Andromeda.Core.DomainTypes

open Andromeda.AvaloniaApp.Components

type AuthMsg =
| StartGame of InstalledGame
| UpgradeGame of InstalledGame
| StartGame of Game
| UpgradeGame of Game
| LookupGameImage of ProductId
| SetGameImage of ProductId * string
| AddNotification of string
| RemoveNotification of string
| AddToTerminalOutput of string
| SetSettings of Settings
| SearchInstalled of initial: bool
| StartGameDownload of ProductInfo * Dlc list * Authentication
| UnpackGame of Settings * DownloadStatus * version: string option
| FinishGameDownload of ProductId
| UpdateDownloadSize of ProductId * int
| UnpackGame of Settings * Game * version: string option
| FinishGameDownload of ProductId * string
| UpdateDownloadSize of ProductId * int<MiB>
| UpdateDownloadInstalling of ProductId
| UpgradeGames
| CacheCheck
Expand Down
Loading

0 comments on commit 3a3ef65

Please sign in to comment.