Skip to content

Commit

Permalink
Landing page (#22598)
Browse files Browse the repository at this point in the history
  • Loading branch information
wendevlin authored Nov 20, 2024
1 parent 6a337cc commit 5b8e63a
Show file tree
Hide file tree
Showing 41 changed files with 1,262 additions and 21 deletions.
32 changes: 32 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,38 @@
"instanceLimit": 1
}
},
{
"label": "Develop Landing Page",
"type": "gulp",
"task": "develop-landing-page",
"problemMatcher": {
"owner": "ha-build",
"source": "ha-build",
"fileLocation": "absolute",
"severity": "error",
"pattern": [
{
"regexp": "(SyntaxError): (.+): (.+) \\((\\d+):(\\d+)\\)",
"severity": 1,
"file": 2,
"message": 3,
"line": 4,
"column": 5
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "Changes detected. Starting compilation",
"endsPattern": "Build done @"
}
},

"isBackground": true,
"group": "build",
"runOptions": {
"instanceLimit": 1
}
},
{
"label": "Develop Demo",
"type": "gulp",
Expand Down
13 changes: 13 additions & 0 deletions build-scripts/bundle.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -327,4 +327,17 @@ module.exports.config = {
},
};
},

landingPage({ isProdBuild, latestBuild }) {
return {
name: "landing-page" + nameSuffix(latestBuild),
entry: {
entrypoint: path.resolve(paths.landingPage_dir, "src/entrypoint.js"),
},
outputPath: outputPath(paths.landingPage_output_root, latestBuild),
publicPath: publicPath(latestBuild),
isProdBuild,
latestBuild,
};
},
};
11 changes: 11 additions & 0 deletions build-scripts/gulp/clean.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,14 @@ gulp.task(
])
)
);

gulp.task(
"clean-landing-page",
gulp.parallel("clean-translations", async () =>
deleteSync([
paths.landingPage_output_root,
paths.landingPage_build,
paths.build_dir,
])
)
);
22 changes: 22 additions & 0 deletions build-scripts/gulp/entry-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,28 @@ gulp.task(
)
);

const LANDING_PAGE_PAGE_ENTRIES = { "index.html": ["entrypoint"] };

gulp.task(
"gen-pages-landing-page-dev",
genPagesDevTask(
LANDING_PAGE_PAGE_ENTRIES,
paths.landingPage_dir,
paths.landingPage_output_root
)
);

gulp.task(
"gen-pages-landing-page-prod",
genPagesProdTask(
LANDING_PAGE_PAGE_ENTRIES,
paths.landingPage_dir,
paths.landingPage_output_root,
paths.landingPage_output_latest,
paths.landingPage_output_es5
)
);

const HASSIO_PAGE_ENTRIES = { "entrypoint.js": ["entrypoint"] };

gulp.task(
Expand Down
16 changes: 16 additions & 0 deletions build-scripts/gulp/gather-static.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ gulp.task("copy-translations-supervisor", async () => {
copyTranslations(staticDir);
});

gulp.task("copy-translations-landing-page", async () => {
const staticDir = paths.landingPage_output_static;
copyTranslations(staticDir);
});

gulp.task("copy-static-supervisor", async () => {
const staticDir = paths.hassio_output_static;
copyLocaleData(staticDir);
Expand Down Expand Up @@ -199,3 +204,14 @@ gulp.task("copy-static-gallery", async () => {
copyLocaleData(paths.gallery_output_static);
copyMdiIcons(paths.gallery_output_static);
});

gulp.task("copy-static-landing-page", async () => {
// Copy landing-page static files
fs.copySync(
path.resolve(paths.landingPage_dir, "public"),
paths.landingPage_output_root
);

copyFonts(paths.landingPage_output_static);
copyTranslations(paths.landingPage_output_static);
});
41 changes: 41 additions & 0 deletions build-scripts/gulp/landing-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import gulp from "gulp";
import "./clean.js";
import "./compress.js";
import "./entry-html.js";
import "./gather-static.js";
import "./gen-icons-json.js";
import "./translations.js";
import "./webpack.js";

gulp.task(
"develop-landing-page",
gulp.series(
async function setEnv() {
process.env.NODE_ENV = "development";
},
"clean-landing-page",
"translations-enable-merge-backend",
"build-landing-page-translations",
"copy-translations-landing-page",
"build-locale-data",
"copy-static-landing-page",
"gen-pages-landing-page-dev",
"webpack-watch-landing-page"
)
);

gulp.task(
"build-landing-page",
gulp.series(
async function setEnv() {
process.env.NODE_ENV = "production";
},
"clean-landing-page",
"build-landing-page-translations",
"copy-translations-landing-page",
"build-locale-data",
"copy-static-landing-page",
"webpack-prod-landing-page",
"gen-pages-landing-page-prod"
)
);
18 changes: 14 additions & 4 deletions build-scripts/gulp/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,14 @@ const createMasterTranslation = () =>

const FRAGMENTS = ["base"];

const toggleSupervisorFragment = async () => {
FRAGMENTS[0] = "supervisor";
const setFragment = (fragment) => async () => {
FRAGMENTS[0] = fragment;
};

const panelFragment = (fragment) =>
fragment !== "base" && fragment !== "supervisor";
fragment !== "base" &&
fragment !== "supervisor" &&
fragment !== "landing-page";

const HASHES = new Map();

Expand Down Expand Up @@ -224,6 +226,9 @@ const createTranslations = async () => {
case "supervisor":
// Supervisor key is at the top level
return [flatten(data.supervisor), ""];
case "landing-page":
// landing-page key is at the top level
return [flatten(data["landing-page"]), ""];
default:
// Create a fragment with only the given panel
return [
Expand Down Expand Up @@ -322,5 +327,10 @@ gulp.task(

gulp.task(
"build-supervisor-translations",
gulp.series(toggleSupervisorFragment, "build-translations")
gulp.series(setFragment("supervisor"), "build-translations")
);

gulp.task(
"build-landing-page-translations",
gulp.series(setFragment("landing-page"), "build-translations")
);
30 changes: 30 additions & 0 deletions build-scripts/gulp/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
createDemoConfig,
createGalleryConfig,
createHassioConfig,
createLandingPageConfig,
} from "../webpack.cjs";

const bothBuilds = (createConfigFunc, params) => [
Expand Down Expand Up @@ -41,6 +42,7 @@ const runDevServer = async ({
contentBase,
port,
listenHost = undefined,
proxy = undefined,
}) => {
if (listenHost === undefined) {
// For dev container, we need to listen on all hosts
Expand All @@ -56,6 +58,7 @@ const runDevServer = async ({
directory: contentBase,
watch: true,
},
proxy,
},
compiler
);
Expand Down Expand Up @@ -199,3 +202,30 @@ gulp.task("webpack-prod-gallery", () =>
})
)
);

gulp.task("webpack-watch-landing-page", () => {
// This command will run forever because we don't close compiler
webpack(
process.env.ES5
? bothBuilds(createLandingPageConfig, { isProdBuild: false })
: createLandingPageConfig({ isProdBuild: false, latestBuild: true })
).watch({ poll: isWsl }, doneHandler());

gulp.watch(
path.join(paths.translations_src, "en.json"),
gulp.series(
"build-landing-page-translations",
"copy-translations-landing-page"
)
);
});

gulp.task("webpack-prod-landing-page", () =>
prodBuild(
bothBuilds(createLandingPageConfig, {
isProdBuild: true,
isStatsBuild: env.isStatsBuild(),
isTestBuild: env.isTestBuild(),
})
)
);
16 changes: 16 additions & 0 deletions build-scripts/paths.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,22 @@ module.exports = {
),
gallery_output_static: path.resolve(__dirname, "../gallery/dist/static"),

landingPage_dir: path.resolve(__dirname, "../landing-page"),
landingPage_build: path.resolve(__dirname, "../landing-page/build"),
landingPage_output_root: path.resolve(__dirname, "../landing-page/dist"),
landingPage_output_latest: path.resolve(
__dirname,
"../landing-page/dist/frontend_latest"
),
landingPage_output_es5: path.resolve(
__dirname,
"../landing-page/dist/frontend_es5"
),
landingPage_output_static: path.resolve(
__dirname,
"../landing-page/dist/static"
),

hassio_dir: path.resolve(__dirname, "../hassio"),
hassio_output_root: path.resolve(__dirname, "../hassio/build"),
hassio_output_static: path.resolve(__dirname, "../hassio/build/static"),
Expand Down
4 changes: 4 additions & 0 deletions build-scripts/webpack.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,15 @@ const createHassioConfig = ({
const createGalleryConfig = ({ isProdBuild, latestBuild }) =>
createWebpackConfig(bundle.config.gallery({ isProdBuild, latestBuild }));

const createLandingPageConfig = ({ isProdBuild, latestBuild }) =>
createWebpackConfig(bundle.config.landingPage({ isProdBuild, latestBuild }));

module.exports = {
createAppConfig,
createDemoConfig,
createCastConfig,
createHassioConfig,
createGalleryConfig,
createLandingPageConfig,
createWebpackConfig,
};
44 changes: 44 additions & 0 deletions landing-page/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Home Assistant OS Landingpage

On initial startup of Home Assistant, HAOS needs to download Home Assistant core before the setup can start.
In this time the [home-assistant/landingpage](https://github.com/home-assistant/landingpage) is serving a "Preparing Home Assistant" page.

## Functionality

- Progress bar to show download
- Show / hide supervisor logs
- Links
- Read our Vision
- Join our community
- Download our app
- DNS issue handler
- if the supervisor is not able to connect to the internet
- Show actions to set dns to google or cloudflare to resolve the issue
- Error handler
- if something with the installation goes wrong, we show the logs

## Develop

It is similar to the core frontend dev.

- frontend repo is building stuff
- landingpage repo can set the frontend repo path and serve the dev frontend

### landingpage dev server

- clone [home-assistant/landingpage](https://github.com/home-assistant/landingpage)
- Add frontend repo as mount to your devcontainer config
- please do not commit this changes, you can remove it after initial dev container build, because the build will keep the options as long as you don't rebuild it.
- `"mounts": ["source=/path/to/hass/frontend,target=/workspaces/frontend,type=bind,consistency=cached"]`
- use the dev container
- start the dev server with following optional env vars:
- `SUPERVISOR_HOST` to have real supervisor data, you can [setup a supervisor remote API access](https://developers.home-assistant.io/docs/supervisor/development/#supervisor-api-access) and set the host of your supervisor. e.g.: `SUPERVISOR_HOST=192.168.0.20:8888`
- `SUPERVISOR_TOKEN` the supervisor api token you get from the Remote API proxy Addon Logs
- `FRONTEND_PATH` the path inside your container should be `/workspaces/frontend`
- example: `SUPERVISOR_TOKEN=abc123 SUPERVISOR_HOST=192.168.0.20:8888 FRONTEND_PATH=/workspaces/frontend go run main.go http.go mdns.go`
- You can also add this into your devcontainer settings, but then it's not so flexible to change if you want to test something else.

### frontend dev server

- install all dependencies
- run `landing-page/script/develop`
8 changes: 8 additions & 0 deletions landing-page/eslintrc.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import rootConfig from "../eslint.config.mjs";

export default [
...rootConfig,
{
rules: {},
},
];
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added landing-page/public/static/icons/favicon.ico
Binary file not shown.
3 changes: 3 additions & 0 deletions landing-page/public/static/icons/logo_ohf.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions landing-page/public/static/icons/ohf.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 5b8e63a

Please sign in to comment.