Skip to content

WIP: Allow generating iconset for HASS icons#1100

Closed
balloob wants to merge 14 commits intomasterfrom
icon-subset
Closed

WIP: Allow generating iconset for HASS icons#1100
balloob wants to merge 14 commits intomasterfrom
icon-subset

Conversation

@balloob
Copy link
Copy Markdown
Member

@balloob balloob commented Apr 18, 2018

WIP until we migrate to Polymer 3

Included icons will be limited to our official icons (the ones we refer in the frontend code). Size of included icons will be reduced from 747K to 38K.

This new gulp script will:

  • Search through our code and find all icons that we use in our official code.
  • Create a new icon set called hass based on icon set mdi with only the icons that we use

To do:

  • We should refer to icons in our code as hass: and update our search regex
  • We should add a config option to the frontend component to allow loading the MDI icons
  • We should also search the python code for used icons??
  • Fork iron-icon to see if missing iconset is mdi and load mdi when missing
  • Update gen-index-html script
  • Convert download mdi script to a pure JS solution instead of a Python/JS hybrid
  • Get it to work. Somehow loading mdi on demand does not seem to work

Not part of this PR but would help loading time:

  • Migrate as much Python code in the backend to use device_class instead of icon.

Comment thread gulp/tasks/hass-icons.js
defs.childNodes = defs.childNodes.filter(icon => icons.has(icon.attrs[0].value));

fs.writeFileSync('hass_frontend/hass_icons.html', parse5.serialize(iconDoc));
console.log(`Home Assistant has ${icons.size} icons.`);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected console statement no-console

Comment thread gulp/tasks/hass-icons.js Outdated

const ironIconset = iconDoc.childNodes[0];
ironIconset.attrs.forEach(attr => {
if (attr.name == 'name') {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected '===' and instead saw '==' eqeqeq

Comment thread gulp/tasks/hass-icons.js Outdated
fs.readFileSync('hass_frontend/mdi.html', { encoding: 'utf-8' }));

const ironIconset = iconDoc.childNodes[0];
ironIconset.attrs.forEach(attr => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected parentheses around arrow function argument having a body with curly braces arrow-parens

Comment thread gulp/tasks/hass-icons.js Outdated
async function generateHassIcons() {
const icons = findIcons();

const iconDoc = parse5.parseFragment(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected newline after '(' function-paren-newline

Comment thread gulp/tasks/hass-icons.js Outdated
let match;
while (match = iconRegEx.exec(content)) {
icons.add(match[0].substr(4));
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary semicolon no-extra-semi

Comment thread gulp/tasks/hass-icons.js
function processFile(filename) {
const content = fs.readFileSync(filename);
let match;
while (match = iconRegEx.exec(content)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected assignment within a 'while' statement no-cond-assign

@andrey-git
Copy link
Copy Markdown
Contributor

Yes, we should also search for python code.

However this makes different namespace difficult

@NovapaX
Copy link
Copy Markdown
Contributor

NovapaX commented Apr 18, 2018

We could fork iron-icon or iron-iconset and let us provide two sources for one iconset. If the primary source (i.e. our packed mdi: subset) fails, load the fallback and try there....
Although a typo in an icon-name would immediately load the fallback iconset.

the advantage of loading the full mdi: on-demand under the same namespace would be that while developing (but also users customizing) you don't need to think about the namespace to use.

@balloob
Copy link
Copy Markdown
Member Author

balloob commented Apr 20, 2018

What if we get rid of all icon definitions on the Python side as part of the core. Instead, icons should be based on device_class or be derived from domain. That way we don't have to search the Python code.

(people can still define icon and it would then load mdi icons on demand.)

@balloob
Copy link
Copy Markdown
Member Author

balloob commented Apr 20, 2018

Well, removing icons from the backend might be quite the task…

image

@balloob
Copy link
Copy Markdown
Member Author

balloob commented Apr 20, 2018

Guess defining an icon in the backed can sometimes make sense, like with Alpha Advantage:

image

@balloob
Copy link
Copy Markdown
Member Author

balloob commented Apr 20, 2018

Probably best approach would be to fork iron-icon to trigger it to load mdi icon set.

We would patch around here:

https://github.com/PolymerElements/iron-icon/blob/7f735696e8d8f6edddb16d78da7da94a3638fa08/iron-icon.html#L182-L184

Comment thread gulp/tasks/hass-icons.js
defs.childNodes = defs.childNodes.filter(icon => icons.has(icon.attrs[0].value));

fs.writeFileSync('hass_frontend/hass_icons.html', parse5.serialize(iconDoc));
console.log(`Home Assistant has ${icons.size} icons.`);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected console statement no-console

@balloob
Copy link
Copy Markdown
Member Author

balloob commented Apr 20, 2018

So I played a bit more with this. Added a new ha-icon which is a fork of iron-icon but with the code attached to load mdi.html on demand. However, this doesn't seem to work 🤔

image

The dynamic panels still use mdi icons. As you can see, icon for Configuration is missing. I have confirmed in the network panel that mdi.html has loaded, yet the iconset doesn't seem to get registered.

Adding some debug statements to ha-icon, I can see ha-icon event listener being triggered and it can find the icon. Yet, when it calls this._iconset.applyIcon, nothing happens.

@NovapaX
Copy link
Copy Markdown
Contributor

NovapaX commented Apr 21, 2018

Could this be related?
PolymerElements/iron-iconset-svg#77

@balloob
Copy link
Copy Markdown
Member Author

balloob commented Apr 23, 2018

That's totally it. When I patch iron-iconset-svg to use the PR by @andrey-git it works.

@balloob
Copy link
Copy Markdown
Member Author

balloob commented Apr 23, 2018

Since I'm already updating the updateIcon method of ha-icon to add mdi on-demand loading, I also introduced a little hack to detect if an iconset might not be loading yet:

b271518

It's not pretty.

Comment thread gulp/tasks/hass-icons.js
const downloadMatch = content.match('(/api/download/polymer/v1/([A-Z0-9-]{36}))');

if (!downloadMatch) {
console.error('Unable to find Polymer v1 download link');

This comment was marked as resolved.

Comment thread gulp/tasks/hass-icons.js
const parse5 = require('parse5');
const getContent = require('../common/http').getContent;

const outputDir = 'hass_frontend';

This comment was marked as resolved.

Comment thread gulp/tasks/hass-icons.js
const downloadMatch = content.match('(/api/download/polymer/v1/([A-Z0-9-]{36}))');

if (!downloadMatch) {
console.error('Unable to find Polymer v1 download link');

This comment was marked as resolved.

@balloob
Copy link
Copy Markdown
Member Author

balloob commented Apr 30, 2018

I've converted the MDI download script to JavaScript, dropping the last Python dependency 🎉

PR on backend to convert built-in panels to use HASS iconset: home-assistant/core#14185

built-in panel icons are hardcoded in the gulp task.

Updated service worker to handle fingerprinting of hass_icons.html correctly and handle the lack of fingerprinting on mdi.html correctly.

@andrey-git
Copy link
Copy Markdown
Contributor

(didn't look at the code yet) I think we should support icons set by platforms (in Python)

@balloob
Copy link
Copy Markdown
Member Author

balloob commented Apr 30, 2018

Problem with icon set per platform is the duplication that might occur when we introduce even more namespaces. We currently have overlap between hass and mdi namespace, but we're assuming that the mdi namespace might not be necessary for basic users.

I prefer if we first see how far sensor device classes is going to get us before we invest time in making icon sets for Python code. In a perfect world, the Python code should not be aware of icons, although I do realize that it's better for us to break that rule here to make the simple things not overly complicated.

const dynamicUrlToDependencies = {};

const staticFingerprinted = [
'mdi.html',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we still have to fingerprint mdi

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. It's only going to be loaded from inside ha-icon and that will reference to it without fingerprint.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a new service worker is installed, it will check the fingerprint and download a new version if it has changed.

@balloob balloob changed the title Allow generating iconset for HASS icons WIP: Allow generating iconset for HASS icons May 3, 2018
@balloob
Copy link
Copy Markdown
Member Author

balloob commented Jun 7, 2018

This has been fixed in #1214.

@balloob balloob closed this Jun 7, 2018
@balloob balloob deleted the icon-subset branch June 7, 2018 18:39
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 8, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants