1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Support non-ascii characters in entity names (#2610)

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2021-04-26 01:58:51 -04:00 committed by GitHub
parent 339502cf4f
commit bcdc0243f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 22 deletions

View File

@ -186,6 +186,7 @@
"filehound": "^1.17.4", "filehound": "^1.17.4",
"filenamify": "^4.1.0", "filenamify": "^4.1.0",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"grapheme-splitter": "^1.0.4",
"handlebars": "^4.7.6", "handlebars": "^4.7.6",
"http-proxy": "^1.18.1", "http-proxy": "^1.18.1",
"immer": "^8.0.1", "immer": "^8.0.1",

View File

@ -19,3 +19,6 @@ export * from "./downloadFile";
export * from "./escapeRegExp"; export * from "./escapeRegExp";
export * from "./tar"; export * from "./tar";
export * from "./type-narrowing"; export * from "./type-narrowing";
import * as iter from "./iter";
export { iter };

25
src/common/utils/iter.ts Normal file
View File

@ -0,0 +1,25 @@
/**
* Create a new type safe empty Iterable
* @returns An `Iterable` that yields 0 items
*/
export function* newEmpty<T>(): Iterable<T> {
return;
}
/**
* Creates a new `Iterable` that yields at most n items from src.
* Does not modify `src` which can be used later.
* @param src An initial iterator
* @param n The maximum number of elements to take from src. Yields up to the floor of `n` and 0 items if n < 0
*/
export function* take<T>(src: Iterable<T>, n: number): Iterable<T> {
outer: for (let i = 0; i < n; i += 1) {
for (const item of src) {
yield item;
continue outer;
}
// if we are here that means that `src` has been exhausted. Don't bother trying again.
break outer;
}
}

View File

@ -2,18 +2,19 @@ import "./hotbar-icon.scss";
import React, { DOMAttributes } from "react"; import React, { DOMAttributes } from "react";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { cssNames, IClassName } from "../../utils"; import { cssNames, IClassName, iter } from "../../utils";
import { Tooltip } from "../tooltip"; import { Tooltip } from "../tooltip";
import { Avatar } from "@material-ui/core"; import { Avatar } from "@material-ui/core";
import { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../../common/catalog"; import { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../../common/catalog";
import { Menu, MenuItem } from "../menu"; import { Menu, MenuItem } from "../menu";
import { Icon } from "../icon"; import { Icon } from "../icon";
import { observable } from "mobx"; import { computed, observable } from "mobx";
import { navigate } from "../../navigation"; import { navigate } from "../../navigation";
import { HotbarStore } from "../../../common/hotbar-store"; import { HotbarStore } from "../../../common/hotbar-store";
import { ConfirmDialog } from "../confirm-dialog"; import { ConfirmDialog } from "../confirm-dialog";
import randomColor from "randomcolor"; import randomColor from "randomcolor";
import { catalogCategoryRegistry } from "../../api/catalog-category-registry"; import { catalogCategoryRegistry } from "../../api/catalog-category-registry";
import GraphemeSplitter from "grapheme-splitter";
interface Props extends DOMAttributes<HTMLElement> { interface Props extends DOMAttributes<HTMLElement> {
entity: CatalogEntity; entity: CatalogEntity;
@ -23,6 +24,22 @@ interface Props extends DOMAttributes<HTMLElement> {
isActive?: boolean; isActive?: boolean;
} }
function getNameParts(name: string): string[] {
const byWhitespace = name.split(/\s+/);
if (byWhitespace.length > 1) {
return byWhitespace;
}
const byDashes = name.split(/[-_]+/);
if (byDashes.length > 1) {
return byDashes;
}
return name.split(/@+/);
}
@observer @observer
export class HotbarIcon extends React.Component<Props> { export class HotbarIcon extends React.Component<Props> {
@observable.deep private contextMenu: CatalogEntityContextMenuContext; @observable.deep private contextMenu: CatalogEntityContextMenuContext;
@ -35,26 +52,18 @@ export class HotbarIcon extends React.Component<Props> {
}; };
} }
get iconString() { @computed get iconString() {
let splittedName = this.props.entity.metadata.name.split(" "); const [rawFirst, rawSecond, rawThird] = getNameParts(this.props.entity.metadata.name);
const splitter = new GraphemeSplitter();
const first = splitter.iterateGraphemes(rawFirst);
const second = rawSecond ? splitter.iterateGraphemes(rawSecond): first;
const third = rawThird ? splitter.iterateGraphemes(rawThird) : iter.newEmpty();
if (splittedName.length === 1) { return [
splittedName = splittedName[0].split("-"); ...iter.take(first, 1),
} ...iter.take(second, 1),
...iter.take(third, 1),
if (splittedName.length === 1) { ].filter(Boolean).join("");
splittedName = splittedName[0].split("@");
}
splittedName = splittedName.map((part) => part.replace(/\W/g, ""));
if (splittedName.length === 1) {
return splittedName[0].substring(0, 2);
} else if (splittedName.length === 2) {
return splittedName[0].substring(0, 1) + splittedName[1].substring(0, 1);
} else {
return splittedName[0].substring(0, 1) + splittedName[1].substring(0, 1) + splittedName[2].substring(0, 1);
}
} }
get badgeIcon() { get badgeIcon() {

View File

@ -6583,7 +6583,7 @@ graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
grapheme-splitter@^1.0.2: grapheme-splitter@^1.0.2, grapheme-splitter@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==