Initial commit

This commit is contained in:
Rene Vergara 2024-01-30 16:42:04 -06:00
commit aefa1d9cfd
Signed by: pitmutt
GPG Key ID: 65122AD495A7F5B2
16 changed files with 10490 additions and 0 deletions

96
.gitignore vendored Normal file
View File

@ -0,0 +1,96 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
.DS_Store
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# Webpack
.webpack/
# Vite
.vite/
# Spago
.spago/
output/
# Electron-Forge
out/

11
README.md Normal file
View File

@ -0,0 +1,11 @@
# halogen-electron
Example of using Halogen and PureScript to create a standalone application.
## Instructions
```bash
npm install
npm run start
```

20
dist/index.html vendored Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<!--<meta-->
<!--http-equiv="Content-Security-Policy"-->
<!--content="default-src 'self'; script-src 'self'"-->
<!--/>-->
<!--<meta-->
<!--http-equiv="X-Content-Security-Policy"-->
<!--content="default-src 'self'; script-src 'self'"-->
<!--/>-->
<title>Vergara Technologies Prototype</title>
<link rel="stylesheet" href="./main.css" />
</head>
<body>
<script src="./index.js" type="module"></script>
</body>
</html>

2
dist/index.js vendored Normal file

File diff suppressed because one or more lines are too long

68
dist/main.css vendored Normal file
View File

@ -0,0 +1,68 @@
:root {
--input-border: #8b8a8b;
--input-focus-h: 245;
--input-focus-s: 100%;
--input-focus-l: 42%;
}
* {
box-sizing: border-box;
}
html {
font-family: sans-serif;
}
button.btn-primary {
border: none;
font-family: inherit;
padding: 0;
cursor: pointer;
@media screen and (-ms-high-contrast: active) {
border: 2px solid currentcolor;
}
}
button.btn-primary {
display: inline-flex;
align-items: center;
justify-content: center;
color: white;
background-color: green;
cursor: pointer;
font-family: inherit;
border-radius: 8px;
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.18);
padding: 0.25em 0.75em;
min-width: 10ch;
min-height: 44px;
text-align: center;
line-height: 1.1;
}
button:disabled {
background-color: gray;
}
.card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
margin: auto;
width: 50%;
text-align: center;
}
.card:hover {
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
.input {
font-size: 16px;
font-size: max(16px, 1em);
font-family: inherit;
padding: 0.25em 0.5em;
background-color: #fff;
border: 2px solid var(--input-border);
border-radius: 4px;
}

30
forge.config.js Normal file
View File

@ -0,0 +1,30 @@
module.exports = {
packagerConfig: {
asar: true,
},
rebuildConfig: {},
makers: [
{
name: '@electron-forge/maker-squirrel',
config: {},
},
{
name: '@electron-forge/maker-zip',
platforms: ['darwin'],
},
{
name: '@electron-forge/maker-deb',
config: {},
},
{
name: '@electron-forge/maker-rpm',
config: {},
},
],
plugins: [
{
name: '@electron-forge/plugin-auto-unpack-natives',
config: {},
},
],
};

53
index.js Normal file
View File

@ -0,0 +1,53 @@
const { app, BrowserWindow } = require('electron');
const path = require('path');
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) {
app.quit();
}
const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
worldSafeExecuteJavaScript: true,
preload: path.join(__dirname, 'preload.js'),
},
});
// and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, 'dist', 'index.html'));
//mainWindow.loadURL('http://localhost:8000/');
// Open the DevTools.
//mainWindow.webContents.openDevTools();
};
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.

6639
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

37
package.json Normal file
View File

@ -0,0 +1,37 @@
{
"name": "halogen-electron",
"productName": "halogen-electron",
"version": "1.0.0",
"description": "My Electron application description",
"main": "index.js",
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish",
"lint": "echo \"No linting configured\"",
"build": "spago build",
"bundle": "spago bundle-app -tdist/index.js -y",
"test": "spago test"
},
"keywords": [],
"author": {
"name": "Rene Vergara",
"email": "rene@vergara.network"
},
"license": "MIT",
"dependencies": {
"electron-squirrel-startup": "^1.0.0",
"esbuild": "^0.19.12"
},
"devDependencies": {
"@electron-forge/cli": "^7.2.0",
"@electron-forge/maker-deb": "^7.2.0",
"@electron-forge/maker-rpm": "^7.2.0",
"@electron-forge/maker-squirrel": "^7.2.0",
"@electron-forge/maker-zip": "^7.2.0",
"@electron-forge/plugin-auto-unpack-natives": "^7.2.0",
"electron": "28.2.0",
"spago": "^0.21.0"
}
}

105
packages.dhall Normal file
View File

@ -0,0 +1,105 @@
{-
Welcome to your new Dhall package-set!
Below are instructions for how to edit this file for most use
cases, so that you don't need to know Dhall to use it.
## Use Cases
Most will want to do one or both of these options:
1. Override/Patch a package's dependency
2. Add a package not already in the default package set
This file will continue to work whether you use one or both options.
Instructions for each option are explained below.
### Overriding/Patching a package
Purpose:
- Change a package's dependency to a newer/older release than the
default package set's release
- Use your own modified version of some dependency that may
include new API, changed API, removed API by
using your custom git repo of the library rather than
the package set's repo
Syntax:
where `entityName` is one of the following:
- dependencies
- repo
- version
-------------------------------
let upstream = --
in upstream
with packageName.entityName = "new value"
-------------------------------
Example:
-------------------------------
let upstream = --
in upstream
with halogen.version = "master"
with halogen.repo = "https://example.com/path/to/git/repo.git"
with halogen-vdom.version = "v4.0.0"
with halogen-vdom.dependencies = [ "extra-dependency" ] # halogen-vdom.dependencies
-------------------------------
### Additions
Purpose:
- Add packages that aren't already included in the default package set
Syntax:
where `<version>` is:
- a tag (i.e. "v4.0.0")
- a branch (i.e. "master")
- commit hash (i.e. "701f3e44aafb1a6459281714858fadf2c4c2a977")
-------------------------------
let upstream = --
in upstream
with new-package-name =
{ dependencies =
[ "dependency1"
, "dependency2"
]
, repo =
"https://example.com/path/to/git/repo.git"
, version =
"<version>"
}
-------------------------------
Example:
-------------------------------
let upstream = --
in upstream
with benchotron =
{ dependencies =
[ "arrays"
, "exists"
, "profunctor"
, "strings"
, "quickcheck"
, "lcg"
, "transformers"
, "foldable-traversable"
, "exceptions"
, "node-fs"
, "node-buffer"
, "node-readline"
, "datetime"
, "now"
]
, repo =
"https://github.com/hdgarrood/purescript-benchotron.git"
, version =
"v7.0.0"
}
-------------------------------
-}
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.15.14-20240126/packages.dhall
sha256:01566c5c6aff61a2eec639a7bb338e8b9321fe081c5ed0a491f4bab3bbf23b92
in upstream

3
preload.js Normal file
View File

@ -0,0 +1,3 @@
// See the Electron documentation for details on how to use preload scripts:
// https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts

29
spago.dhall Normal file
View File

@ -0,0 +1,29 @@
{-
Welcome to a Spago project!
You can edit this file as you like.
Need help? See the following resources:
- Spago documentation: https://github.com/purescript/spago
- Dhall language tour: https://docs.dhall-lang.org/tutorials/Language-Tour.html
When creating a new Spago project, you can use
`spago init --no-comments` or `spago init -C`
to generate this file without the comments in this block.
-}
{ name = "puretimer"
, dependencies =
[ "aff"
, "console"
, "effect"
, "either"
, "formatters"
, "halogen"
, "halogen-subscriptions"
, "integers"
, "maybe"
, "prelude"
, "tailrec"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
}

124
src/App/Timer.purs Normal file
View File

@ -0,0 +1,124 @@
module App.Timer where
import Data.Formatter.Number
import Data.Int
import Prelude
import Control.Monad.Rec.Class (forever)
import Data.Either (Either(..))
import Data.Maybe (Maybe(..))
import Effect.Aff (Milliseconds(..))
import Effect.Aff as Aff
import Effect.Aff.Class (class MonadAff)
import Effect.Class.Console (log)
import Halogen as H
import Halogen.HTML as HH
import Halogen.HTML.Events as HE
import Halogen.HTML.Properties as HP
import Halogen.Subscription as HS
type State =
{ running :: Boolean
, base :: Int
, count :: Int
}
data Action
= Start
| Tick
| Stop
| Reset
| Increment
| Decrement
| Initialize
component :: forall q i o m. MonadAff m => H.Component q i o m
component =
H.mkComponent
{ initialState: \_ -> { running: false, base: 0, count: 0 }
, render
, eval: H.mkEval H.defaultEval { handleAction = handleAction, initialize = Just Initialize }
}
render :: forall cs m. State -> H.ComponentHTML Action cs m
render state =
HH.div
[ css "card"
]
[ HH.h2_ [ HH.text "PureTimer" ]
, HH.p_ [ showTime state.count timeFormatter ]
, HH.button
[ css "btn-primary"
, HP.disabled $ state.running || state.base == 0
, HE.onClick \_ -> Decrement
]
[ HH.text "-1m" ]
, HH.button
[ css "btn-primary"
, HP.disabled state.running
, HE.onClick \_ -> Increment
]
[ HH.text "+1m" ]
, HH.div_
[ HH.button
[ css "btn-primary"
, HP.disabled state.running
, HE.onClick \_ -> Start
]
[ HH.text "Start" ]
, HH.button
[ css "btn-primary"
, HP.enabled state.running
, HE.onClick \_ -> Stop
]
[ HH.text "Stop" ]
, HH.p_ [ HH.text $ if state.running then "Running" else "Stopped" ]
]
, HH.div_
[ HH.button
[ css "btn-primary"
, HP.disabled state.running
, HE.onClick \_ -> Reset
]
[ HH.text "Reset" ]
]
]
handleAction :: forall cs o m. MonadAff m => Action -> H.HalogenM State Action cs o m Unit
handleAction = case _ of
Initialize -> do
_ <- H.subscribe =<< timer Tick
pure unit
Increment -> H.modify_ \st -> st { count = st.base + 60, base = st.base + 60 }
Decrement -> H.modify_ \st -> st { count = st.base - 60, base = st.base - 60 }
Start -> do
H.modify_ \st -> st { running = true }
handleAction Tick
Tick -> do
s <- H.get
if s.count > 0 then
if s.running then do
H.put $ { running: s.running, count: s.count - 1, base: s.base }
else pure unit
else handleAction Stop
Stop -> H.modify_ \st -> st { running = false, count = st.count, base = st.base }
Reset -> H.modify_ \st -> st { count = st.base }
css :: forall r i. String -> HH.IProp (class :: String | r) i
css = HP.class_ <<< HH.ClassName
showTime :: forall cs m. Int -> Either String Formatter -> H.ComponentHTML Action cs m
showTime secs fmt = case fmt of
Left s -> HH.text s
Right f -> HH.text $ format f (toNumber (secs / 60)) <> ":" <> format f (toNumber (secs `mod` 60))
timeFormatter :: Either String Formatter
timeFormatter = parseFormatString "00"
timer :: forall m a. MonadAff m => a -> m (HS.Emitter a)
timer val = do
{ emitter, listener } <- H.liftEffect HS.create
_ <- H.liftAff $ Aff.forkAff $ forever do
Aff.delay $ Milliseconds 1000.0
H.liftEffect $ HS.notify listener val
pure emitter

13
src/Main.purs Normal file
View File

@ -0,0 +1,13 @@
module Main where
import Prelude
import Effect (Effect)
import Halogen.Aff as HA
import Halogen.VDom.Driver (runUI)
import App.Timer as Timer
main :: Effect Unit
main = HA.runHalogenAff do
body <- HA.awaitBody
runUI Timer.component unit body

11
test/Main.purs Normal file
View File

@ -0,0 +1,11 @@
module Test.Main where
import Prelude
import Effect (Effect)
import Effect.Class.Console (log)
main :: Effect Unit
main = do
log "🍝"
log "You should add some tests."

3249
yarn.lock Normal file

File diff suppressed because it is too large Load Diff