commit 183219d6e1b454e0f9246f6eb8b25b03b6995f32 Author: Marc Scholten Date: Sun Apr 16 12:31:32 2023 +0200 Initial project setup diff --git a/.ghci b/.ghci new file mode 100644 index 0000000..01a4ea9 --- /dev/null +++ b/.ghci @@ -0,0 +1,4 @@ +:set -XNoImplicitPrelude +:def source readFile +:source build/ihp-lib/applicationGhciConfig +import IHP.Prelude diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6f3a3fa --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto eol=lf +*.sql text +*.hs text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..06f03b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +.envrc +.idea +tmp +result +node_modules +bin +*.iml +Generated +dist +dist-newstyle +*.dyn_hi +*.dyn_o +*.hi +*.o +build +gen +del +static/prod.* +Config/client_session_key.aes + +# Ignore locally checked out IHP version +IHP diff --git a/.stylish-haskell.yaml b/.stylish-haskell.yaml new file mode 100644 index 0000000..b803c01 --- /dev/null +++ b/.stylish-haskell.yaml @@ -0,0 +1,415 @@ +# stylish-haskell configuration file +# ================================== + +# The stylish-haskell tool is mainly configured by specifying steps. These steps +# are a list, so they have an order, and one specific step may appear more than +# once (if needed). Each file is processed by these steps in the given order. +steps: + # Convert some ASCII sequences to their Unicode equivalents. This is disabled + # by default. + # - unicode_syntax: + # # In order to make this work, we also need to insert the UnicodeSyntax + # # language pragma. If this flag is set to true, we insert it when it's + # # not already present. You may want to disable it if you configure + # # language extensions using some other method than pragmas. Default: + # # true. + # add_language_pragma: true + + # Format module header + # + # Currently, this option is not configurable and will format all exports and + # module declarations to minimize diffs + # + # - module_header: + # # How many spaces use for indentation in the module header. + # indent: 4 + # + # # Should export lists be sorted? Sorting is only performed within the + # # export section, as delineated by Haddock comments. + # sort: true + # + # # See `separate_lists` for the `imports` step. + # separate_lists: true + # + # # When to break the "where". + # # Possible values: + # # - exports: only break when there is an explicit export list. + # # - single: only break when the export list counts more than one export. + # # - inline: only break when the export list is too long. This is + # # determined by the `columns` setting. Not applicable when the export + # # list contains comments as newlines will be required. + # # - always: always break before the "where". + # break_where: exports + # + # # Where to put open bracket + # # Possible values: + # # - same_line: put open bracket on the same line as the module name, before the + # # comment of the module + # # - next_line: put open bracket on the next line, after module comment + # open_bracket: next_line + + # Format record definitions. This is disabled by default. + # + # You can control the layout of record fields. The only rules that can't be configured + # are these: + # + # - "|" is always aligned with "=" + # - "," in fields is always aligned with "{" + # - "}" is likewise always aligned with "{" + # + # - records: + # # How to format equals sign between type constructor and data constructor. + # # Possible values: + # # - "same_line" -- leave "=" AND data constructor on the same line as the type constructor. + # # - "indent N" -- insert a new line and N spaces from the beginning of the next line. + # equals: "indent 2" + # + # # How to format first field of each record constructor. + # # Possible values: + # # - "same_line" -- "{" and first field goes on the same line as the data constructor. + # # - "indent N" -- insert a new line and N spaces from the beginning of the data constructor + # first_field: "indent 2" + # + # # How many spaces to insert between the column with "," and the beginning of the comment in the next line. + # field_comment: 2 + # + # # How many spaces to insert before "deriving" clause. Deriving clauses are always on separate lines. + # deriving: 2 + # + # # How many spaces to insert before "via" clause counted from indentation of deriving clause + # # Possible values: + # # - "same_line" -- "via" part goes on the same line as "deriving" keyword. + # # - "indent N" -- insert a new line and N spaces from the beginning of "deriving" keyword. + # via: "indent 2" + # + # # Sort typeclass names in the "deriving" list alphabetically. + # sort_deriving: true + # + # # Whether or not to break enums onto several lines + # # + # # Default: false + # break_enums: false + # + # # Whether or not to break single constructor data types before `=` sign + # # + # # Default: true + # break_single_constructors: true + # + # # Whether or not to curry constraints on function. + # # + # # E.g: @allValues :: Enum a => Bounded a => Proxy a -> [a]@ + # # + # # Instead of @allValues :: (Enum a, Bounded a) => Proxy a -> [a]@ + # # + # # Default: false + # curried_context: false + + # Align the right hand side of some elements. This is quite conservative + # and only applies to statements where each element occupies a single + # line. + # Possible values: + # - always - Always align statements. + # - adjacent - Align statements that are on adjacent lines in groups. + # - never - Never align statements. + # All default to always. + - simple_align: + cases: always + top_level_patterns: always + records: always + multi_way_if: always + + # Import cleanup + - imports: + # There are different ways we can align names and lists. + # + # - global: Align the import names and import list throughout the entire + # file. + # + # - file: Like global, but don't add padding when there are no qualified + # imports in the file. + # + # - group: Only align the imports per group (a group is formed by adjacent + # import lines). + # + # - none: Do not perform any alignment. + # + # Default: global. + align: none + + # The following options affect only import list alignment. + # + # List align has following options: + # + # - after_alias: Import list is aligned with end of import including + # 'as' and 'hiding' keywords. + # + # > import qualified Data.List as List (concat, foldl, foldr, head, + # > init, last, length) + # + # - with_alias: Import list is aligned with start of alias or hiding. + # + # > import qualified Data.List as List (concat, foldl, foldr, head, + # > init, last, length) + # + # - with_module_name: Import list is aligned `list_padding` spaces after + # the module name. + # + # > import qualified Data.List as List (concat, foldl, foldr, head, + # init, last, length) + # + # This is mainly intended for use with `pad_module_names: false`. + # + # > import qualified Data.List as List (concat, foldl, foldr, head, + # init, last, length, scanl, scanr, take, drop, + # sort, nub) + # + # - new_line: Import list starts always on new line. + # + # > import qualified Data.List as List + # > (concat, foldl, foldr, head, init, last, length) + # + # - repeat: Repeat the module name to align the import list. + # + # > import qualified Data.List as List (concat, foldl, foldr, head) + # > import qualified Data.List as List (init, last, length) + # + # Default: after_alias + list_align: after_alias + + # Right-pad the module names to align imports in a group: + # + # - true: a little more readable + # + # > import qualified Data.List as List (concat, foldl, foldr, + # > init, last, length) + # > import qualified Data.List.Extra as List (concat, foldl, foldr, + # > init, last, length) + # + # - false: diff-safe + # + # > import qualified Data.List as List (concat, foldl, foldr, init, + # > last, length) + # > import qualified Data.List.Extra as List (concat, foldl, foldr, + # > init, last, length) + # + # Default: true + pad_module_names: true + + # Long list align style takes effect when import is too long. This is + # determined by 'columns' setting. + # + # - inline: This option will put as much specs on same line as possible. + # + # - new_line: Import list will start on new line. + # + # - new_line_multiline: Import list will start on new line when it's + # short enough to fit to single line. Otherwise it'll be multiline. + # + # - multiline: One line per import list entry. + # Type with constructor list acts like single import. + # + # > import qualified Data.Map as M + # > ( empty + # > , singleton + # > , ... + # > , delete + # > ) + # + # Default: inline + long_list_align: inline + + # Align empty list (importing instances) + # + # Empty list align has following options + # + # - inherit: inherit list_align setting + # + # - right_after: () is right after the module name: + # + # > import Vector.Instances () + # + # Default: inherit + empty_list_align: inherit + + # List padding determines indentation of import list on lines after import. + # This option affects 'long_list_align'. + # + # - : constant value + # + # - module_name: align under start of module name. + # Useful for 'file' and 'group' align settings. + # + # Default: 4 + list_padding: 4 + + # Separate lists option affects formatting of import list for type + # or class. The only difference is single space between type and list + # of constructors, selectors and class functions. + # + # - true: There is single space between Foldable type and list of it's + # functions. + # + # > import Data.Foldable (Foldable (fold, foldl, foldMap)) + # + # - false: There is no space between Foldable type and list of it's + # functions. + # + # > import Data.Foldable (Foldable(fold, foldl, foldMap)) + # + # Default: true + separate_lists: true + + # Space surround option affects formatting of import lists on a single + # line. The only difference is single space after the initial + # parenthesis and a single space before the terminal parenthesis. + # + # - true: There is single space associated with the enclosing + # parenthesis. + # + # > import Data.Foo ( foo ) + # + # - false: There is no space associated with the enclosing parenthesis + # + # > import Data.Foo (foo) + # + # Default: false + space_surround: false + + # Post qualify option moves any qualifies found in import declarations + # to the end of the declaration. This also adjust padding for any + # unqualified import declarations. + # + # - true: Qualified as is moved to the end of the + # declaration. + # + # > import Data.Bar + # > import Data.Foo qualified as F + # + # - false: Qualified remains in the default location and unqualified + # imports are padded to align with qualified imports. + # + # > import Data.Bar + # > import qualified Data.Foo as F + # + # Default: false + post_qualify: false + + # Language pragmas + - language_pragmas: + # We can generate different styles of language pragma lists. + # + # - vertical: Vertical-spaced language pragmas, one per line. + # + # - compact: A more compact style. + # + # - compact_line: Similar to compact, but wrap each line with + # `{-# LANGUAGE #-}'. + # + # - vertical_compact: Similar to vertical, but use only one language pragma. + # + # Default: vertical. + style: vertical + + # Align affects alignment of closing pragma brackets. + # + # - true: Brackets are aligned in same column. + # + # - false: Brackets are not aligned together. There is only one space + # between actual import and closing bracket. + # + # Default: true + align: true + + # stylish-haskell can detect redundancy of some language pragmas. If this + # is set to true, it will remove those redundant pragmas. Default: true. + remove_redundant: true + + # Language prefix to be used for pragma declaration, this allows you to + # use other options non case-sensitive like "language" or "Language". + # If a non correct String is provided, it will default to: LANGUAGE. + language_prefix: LANGUAGE + + # Replace tabs by spaces. This is disabled by default. + # - tabs: + # # Number of spaces to use for each tab. Default: 8, as specified by the + # # Haskell report. + # spaces: 8 + + # Remove trailing whitespace + - trailing_whitespace: {} + + # Squash multiple spaces between the left and right hand sides of some + # elements into single spaces. Basically, this undoes the effect of + # simple_align but is a bit less conservative. + # - squash: {} + +# A common setting is the number of columns (parts of) code will be wrapped +# to. Different steps take this into account. +# +# Set this to null to disable all line wrapping. +# +# Default: 80. +columns: 80 + +# By default, line endings are converted according to the OS. You can override +# preferred format here. +# +# - native: Native newline format. CRLF on Windows, LF on other OSes. +# +# - lf: Convert to LF ("\n"). +# +# - crlf: Convert to CRLF ("\r\n"). +# +# Default: native. +newline: native + +# Sometimes, language extensions are specified in a cabal file or from the +# command line instead of using language pragmas in the file. stylish-haskell +# needs to be aware of these, so it can parse the file correctly. +# +# No language extensions are enabled by default. +language_extensions: + - BangPatterns + - BlockArguments + - BlockArguments + - DataKinds + - DefaultSignatures + - DeriveDataTypeable + - DeriveGeneric + - DerivingVia + - DisambiguateRecordFields + - DuplicateRecordFields + - EmptyDataDeriving + - FlexibleContexts + - FlexibleInstances + - FunctionalDependencies + - ImplicitParams + - InstanceSigs + - LambdaCase + - MultiParamTypeClasses + - MultiWayIf + - MultiWayIf + - NamedFieldPuns + - NoImplicitPrelude + - OverloadedLabels + - OverloadedStrings + - PackageImports + - PartialTypeSignatures + - PartialTypeSignatures + - QuasiQuotes + - Rank2Types + - RecordWildCards + - ScopedTypeVariables + - StandaloneDeriving + - TemplateHaskell + - TypeApplications + - TypeFamilies + - TypeOperators + - TypeSynonymInstances + - UndecidableInstances + +# Attempt to find the cabal file in ancestors of the current directory, and +# parse options (currently only language extensions) from that. +# +# Default: true +cabal: true diff --git a/App.cabal b/App.cabal new file mode 100644 index 0000000..9463cfc --- /dev/null +++ b/App.cabal @@ -0,0 +1,71 @@ +-- This file is only a stub file, please see default.nix for adding dependencies. +-- +-- Learn more about dependency management in IHP: https://ihp.digitallyinduced.com/Guide/package-management.html +-- +-- If you're looking at this file because you're trying to integrate a HLS or other tooling with your IHP project, check out the documentation on Editors and Tooling: https://ihp.digitallyinduced.com/Guide/editors.html +-- +-- This cabal file is inside your project as some haskell tools only work when there's a cabal file. It's not actually used for anything besides providing support for haskell tools. +-- + +name: App +version: 0.1.0.0 +-- synopsis: +-- description: +license: AllRightsReserved +license-file: LICENSE +author: Developers +maintainer: developers@example.com +-- copyright: +-- category: +build-type: Simple +cabal-version: >=1.10 + +executable App + main-is: Main.hs + -- other-modules: + -- other-extensions: + build-depends: + ihp, + base, + wai, + text + hs-source-dirs: . + default-language: Haskell2010 + extensions: + OverloadedStrings + , NoImplicitPrelude + , ImplicitParams + , Rank2Types + , DisambiguateRecordFields + , NamedFieldPuns + , DuplicateRecordFields + , OverloadedLabels + , FlexibleContexts + , TypeSynonymInstances + , FlexibleInstances + , QuasiQuotes + , TypeFamilies + , PackageImports + , ScopedTypeVariables + , RecordWildCards + , TypeApplications + , DataKinds + , InstanceSigs + , DeriveGeneric + , MultiParamTypeClasses + , TypeOperators + , DeriveDataTypeable + , MultiWayIf + , UndecidableInstances + , BlockArguments + , PartialTypeSignatures + , LambdaCase + , DefaultSignatures + , EmptyDataDeriving + , BangPatterns + , BlockArguments + , MultiWayIf + , FunctionalDependencies + , PartialTypeSignatures + , StandaloneDeriving + , DerivingVia \ No newline at end of file diff --git a/Application/Fixtures.sql b/Application/Fixtures.sql new file mode 100644 index 0000000..e69de29 diff --git a/Application/Helper/Controller.hs b/Application/Helper/Controller.hs new file mode 100644 index 0000000..3aa7c2a --- /dev/null +++ b/Application/Helper/Controller.hs @@ -0,0 +1,5 @@ +module Application.Helper.Controller where + +import IHP.ControllerPrelude + +-- Here you can add functions which are available in all your controllers \ No newline at end of file diff --git a/Application/Helper/View.hs b/Application/Helper/View.hs new file mode 100644 index 0000000..ce8ac64 --- /dev/null +++ b/Application/Helper/View.hs @@ -0,0 +1,5 @@ +module Application.Helper.View where + +import IHP.ViewPrelude + +-- Here you can add functions which are available in all your views \ No newline at end of file diff --git a/Application/Schema.sql b/Application/Schema.sql new file mode 100644 index 0000000..b743c66 --- /dev/null +++ b/Application/Schema.sql @@ -0,0 +1 @@ +-- Your database schema. Use the Schema Designer at http://localhost:8001/ to add some tables. diff --git a/Application/Script/Prelude.hs b/Application/Script/Prelude.hs new file mode 100644 index 0000000..66feaec --- /dev/null +++ b/Application/Script/Prelude.hs @@ -0,0 +1,12 @@ +module Application.Script.Prelude +( module IHP.ControllerPrelude +, module Generated.Types +, module IHP.Prelude +, module IHP.ScriptSupport +) +where + +import IHP.Prelude +import IHP.ControllerPrelude +import Generated.Types +import IHP.ScriptSupport \ No newline at end of file diff --git a/Config/Config.hs b/Config/Config.hs new file mode 100644 index 0000000..7284574 --- /dev/null +++ b/Config/Config.hs @@ -0,0 +1,11 @@ +module Config where + +import IHP.Prelude +import IHP.Environment +import IHP.FrameworkConfig + +config :: ConfigBuilder +config = do + -- See https://ihp.digitallyinduced.com/Guide/config.html + -- for what you can do here + pure () \ No newline at end of file diff --git a/Config/nix/haskell-packages/.keep b/Config/nix/haskell-packages/.keep new file mode 100644 index 0000000..e69de29 diff --git a/Config/nix/nixpkgs-config.nix b/Config/nix/nixpkgs-config.nix new file mode 100644 index 0000000..fc530de --- /dev/null +++ b/Config/nix/nixpkgs-config.nix @@ -0,0 +1,7 @@ +# See https://ihp.digitallyinduced.com/Guide/package-management.html +{ ihp, additionalNixpkgsOptions, ... }: +import "${toString ihp}/NixSupport/make-nixpkgs-from-options.nix" { + ihp = ihp; + haskellPackagesDir = ./haskell-packages/.; + additionalNixpkgsOptions = additionalNixpkgsOptions; +} \ No newline at end of file diff --git a/Main.hs b/Main.hs new file mode 100644 index 0000000..be5faf8 --- /dev/null +++ b/Main.hs @@ -0,0 +1,21 @@ +module Main where +import IHP.Prelude + +import Config +import qualified IHP.Server +import IHP.RouterSupport +import IHP.FrameworkConfig +import IHP.Job.Types +import Web.FrontController +import Web.Types + +instance FrontController RootApplication where + controllers = [ + mountFrontController WebApplication + ] + +instance Worker RootApplication where + workers _ = [] + +main :: IO () +main = IHP.Server.run config diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..15b7a26 --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +ifneq ($(wildcard IHP/.*),) +IHP = IHP/lib/IHP +else +ifneq ($(wildcard build/ihp-lib),) +IHP = build/ihp-lib +else +ifneq ($(shell which RunDevServer),) +IHP = $(shell dirname $$(which RunDevServer))/../lib/IHP +else +IHP = $(error IHP not found! Run the following command to fix this: nix-shell --run 'make .envrc' ) +endif +endif +endif + +CSS_FILES += ${IHP}/static/vendor/bootstrap.min.css +CSS_FILES += ${IHP}/static/vendor/flatpickr.min.css +CSS_FILES += static/app.css + +JS_FILES += ${IHP}/static/vendor/jquery-3.6.0.slim.min.js +JS_FILES += ${IHP}/static/vendor/timeago.js +JS_FILES += ${IHP}/static/vendor/popper.min.js +JS_FILES += ${IHP}/static/vendor/bootstrap.min.js +JS_FILES += ${IHP}/static/vendor/flatpickr.js +JS_FILES += ${IHP}/static/helpers.js +JS_FILES += ${IHP}/static/vendor/morphdom-umd.min.js +JS_FILES += ${IHP}/static/vendor/turbolinks.js +JS_FILES += ${IHP}/static/vendor/turbolinksInstantClick.js +JS_FILES += ${IHP}/static/vendor/turbolinksMorphdom.js + +include ${IHP}/Makefile.dist + diff --git a/Setup.hs b/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/Web/Controller/Prelude.hs b/Web/Controller/Prelude.hs new file mode 100644 index 0000000..106e039 --- /dev/null +++ b/Web/Controller/Prelude.hs @@ -0,0 +1,13 @@ +module Web.Controller.Prelude +( module Web.Types +, module Application.Helper.Controller +, module IHP.ControllerPrelude +, module Generated.Types +) +where + +import Web.Types +import Application.Helper.Controller +import IHP.ControllerPrelude +import Generated.Types +import Web.Routes diff --git a/Web/Controller/Static.hs b/Web/Controller/Static.hs new file mode 100644 index 0000000..0296557 --- /dev/null +++ b/Web/Controller/Static.hs @@ -0,0 +1,6 @@ +module Web.Controller.Static where +import Web.Controller.Prelude +import Web.View.Static.Welcome + +instance Controller StaticController where + action WelcomeAction = render WelcomeView diff --git a/Web/FrontController.hs b/Web/FrontController.hs new file mode 100644 index 0000000..e1fb78a --- /dev/null +++ b/Web/FrontController.hs @@ -0,0 +1,19 @@ +module Web.FrontController where + +import IHP.RouterPrelude +import Web.Controller.Prelude +import Web.View.Layout (defaultLayout) + +-- Controller Imports +import Web.Controller.Static + +instance FrontController WebApplication where + controllers = + [ startPage WelcomeAction + -- Generator Marker + ] + +instance InitControllerContext WebApplication where + initContext = do + setLayout defaultLayout + initAutoRefresh diff --git a/Web/Routes.hs b/Web/Routes.hs new file mode 100644 index 0000000..98b0b2b --- /dev/null +++ b/Web/Routes.hs @@ -0,0 +1,7 @@ +module Web.Routes where +import IHP.RouterPrelude +import Generated.Types +import Web.Types + +-- Generator Marker +instance AutoRoute StaticController \ No newline at end of file diff --git a/Web/Types.hs b/Web/Types.hs new file mode 100644 index 0000000..d48bddd --- /dev/null +++ b/Web/Types.hs @@ -0,0 +1,10 @@ +module Web.Types where + +import IHP.Prelude +import IHP.ModelSupport +import Generated.Types + +data WebApplication = WebApplication deriving (Eq, Show) + + +data StaticController = WelcomeAction deriving (Eq, Show, Data) diff --git a/Web/View/Layout.hs b/Web/View/Layout.hs new file mode 100644 index 0000000..dea1950 --- /dev/null +++ b/Web/View/Layout.hs @@ -0,0 +1,73 @@ +module Web.View.Layout (defaultLayout, Html) where + +import IHP.ViewPrelude +import IHP.Environment +import qualified Text.Blaze.Html5 as H +import qualified Text.Blaze.Html5.Attributes as A +import Generated.Types +import IHP.Controller.RequestContext +import Web.Types +import Web.Routes +import Application.Helper.View + +defaultLayout :: Html -> Html +defaultLayout inner = H.docTypeHtml ! A.lang "en" $ [hsx| + + {metaTags} + + {stylesheets} + {scripts} + + {pageTitleOrDefault "App"} + + +
+ {renderFlashMessages} + {inner} +
+ +|] + +-- The 'assetPath' function used below appends a `?v=SOME_VERSION` to the static assets in production +-- This is useful to avoid users having old CSS and JS files in their browser cache once a new version is deployed +-- See https://ihp.digitallyinduced.com/Guide/assets.html for more details + +stylesheets :: Html +stylesheets = [hsx| + + + + |] + +scripts :: Html +scripts = [hsx| + {when isDevelopment devScripts} + + + + + + + + + + + + + |] + +devScripts :: Html +devScripts = [hsx| + + |] + +metaTags :: Html +metaTags = [hsx| + + + + + + + {autoRefreshMeta} +|] diff --git a/Web/View/Prelude.hs b/Web/View/Prelude.hs new file mode 100644 index 0000000..86a2e47 --- /dev/null +++ b/Web/View/Prelude.hs @@ -0,0 +1,14 @@ +module Web.View.Prelude +( module IHP.ViewPrelude +, module Web.View.Layout +, module Generated.Types +, module Web.Types +, module Application.Helper.View +) where + +import IHP.ViewPrelude +import Web.View.Layout +import Generated.Types +import Web.Types +import Web.Routes () +import Application.Helper.View diff --git a/Web/View/Static/Welcome.hs b/Web/View/Static/Welcome.hs new file mode 100644 index 0000000..148948f --- /dev/null +++ b/Web/View/Static/Welcome.hs @@ -0,0 +1,42 @@ +module Web.View.Static.Welcome where +import Web.View.Prelude + +data WelcomeView = WelcomeView + +instance View WelcomeView where + html WelcomeView = [hsx| +
+
+

+ IHP +

+ +

+ It's working! +

+ +

+ Your new application is up and running. +

+ +

+ Join our community on Slack! +

+ + + Learn the Next Steps in the Documentation + +
+
+ +
+ /ihp-welcome-icon +

+ You can modify this start page by making changes to "./Web/View/Static/Welcome.hs". +

+
+|] \ No newline at end of file diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..15f24a4 --- /dev/null +++ b/default.nix @@ -0,0 +1,22 @@ +let + ihp = builtins.fetchGit { + url = "https://github.com/digitallyinduced/ihp.git"; + rev = "113ce378747ce129f293d5cef504acbb3bca44ca"; + }; + haskellEnv = import "${ihp}/NixSupport/default.nix" { + ihp = ihp; + haskellDeps = p: with p; [ + cabal-install + base + wai + text + hlint + p.ihp + ]; + otherDeps = p: with p; [ + # Native dependencies, e.g. imagemagick + ]; + projectPath = ./.; + }; +in + haskellEnv diff --git a/hie.yaml b/hie.yaml new file mode 100644 index 0000000..0c8a861 --- /dev/null +++ b/hie.yaml @@ -0,0 +1,4 @@ +# Used by haskell-language-server to find GHC settings +cradle: + bios: + program: build/ihp-lib/.hie-bios \ No newline at end of file diff --git a/start b/start new file mode 100755 index 0000000..679a691 --- /dev/null +++ b/start @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Script to start the local dev server + +set -e + +# On macOS the default max count of open files is 256. IHP needs atleast 1024 to run well. +# +# The wai-static-middleware sometimes doesn't close it's file handles directly (likely because of it's use of lazy bytestrings) +# and then we usually hit the file limit of 256 at some point. With 1024 the limit is usually never hit as the GC kicks in earlier +# and will close the remaining lazy bytestring handles. +if [[ $OSTYPE == 'darwin'* ]]; then + ulimit -n 4096 +fi + +# Unless the RunDevServer binary is available, we rebuild the .envrc cache with nix-shell +# and config cachix for using our binary cache +command -v RunDevServer >/dev/null 2>&1 \ + || { echo "PATH_add $(nix-shell -j auto --cores 0 --run 'printf %q $PATH')" > .envrc; } + +# Now we have to load the PATH variable from the .envrc cache +direnv allow +eval "$(direnv hook bash)" +eval "$(direnv export bash)" + +# You can define custom env vars here: +# export CUSTOM_ENV_VAR=".." + +# Finally start the dev server +RunDevServer diff --git a/static/app.css b/static/app.css new file mode 100644 index 0000000..e69de29 diff --git a/static/app.js b/static/app.js new file mode 100644 index 0000000..1012d94 --- /dev/null +++ b/static/app.js @@ -0,0 +1,3 @@ +$(document).on('ready turbolinks:load', function () { + // This is called on the first page load *and* also when the page is changed by turbolinks +}); \ No newline at end of file diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/static/ihp-welcome-icon.svg b/static/ihp-welcome-icon.svg new file mode 100644 index 0000000..6a3b4dc --- /dev/null +++ b/static/ihp-welcome-icon.svg @@ -0,0 +1 @@ +experience design