Remove labels from genre icons (#37)

This commit is contained in:
Simon J
2021-08-30 13:01:59 +10:00
committed by GitHub
parent 89accef1e6
commit ca9bf2fc04
9 changed files with 8 additions and 226 deletions

View File

@@ -143,8 +143,6 @@ BONOB_SCROBBLE_TRACKS | true | Whether to scrobble the playing of a track if it
BONOB_REPORT_NOW_PLAYING | true | Whether to report a track as now playing BONOB_REPORT_NOW_PLAYING | true | Whether to report a track as now playing
BONOB_ICON_FOREGROUND_COLOR | undefined | Icon foreground color in sonos app, must be a valid [svg color](https://www.december.com/html/spec/colorsvg.html) BONOB_ICON_FOREGROUND_COLOR | undefined | Icon foreground color in sonos app, must be a valid [svg color](https://www.december.com/html/spec/colorsvg.html)
BONOB_ICON_BACKGROUND_COLOR | undefined | Icon background color in sonos app, must be a valid [svg color](https://www.december.com/html/spec/colorsvg.html) BONOB_ICON_BACKGROUND_COLOR | undefined | Icon background color in sonos app, must be a valid [svg color](https://www.december.com/html/spec/colorsvg.html)
BONOB_ICON_FONT_COLOR | undefined | Icon font color in sonos app, must be a valid [svg color](https://www.december.com/html/spec/colorsvg.html)
BONOB_ICON_FONT_FAMILY | undefined | Icon font family in sonos app
## Initialising service within sonos app ## Initialising service within sonos app

View File

@@ -33,8 +33,6 @@ export default function () {
icons: { icons: {
foregroundColor: wordFrom("BONOB_ICON_FOREGROUND_COLOR"), foregroundColor: wordFrom("BONOB_ICON_FOREGROUND_COLOR"),
backgroundColor: wordFrom("BONOB_ICON_BACKGROUND_COLOR"), backgroundColor: wordFrom("BONOB_ICON_BACKGROUND_COLOR"),
fontColor: wordFrom("BONOB_ICON_FONT_COLOR"),
fontFamily: wordFrom("BONOB_ICON_FONT_FAMILY")
}, },
sonos: { sonos: {
serviceName: process.env["BONOB_SONOS_SERVICE_NAME"] || "bonob", serviceName: process.env["BONOB_SONOS_SERVICE_NAME"] || "bonob",

View File

@@ -16,9 +16,6 @@ export type Transformation = {
viewPortIncreasePercent: number | undefined; viewPortIncreasePercent: number | undefined;
backgroundColor: string | undefined; backgroundColor: string | undefined;
foregroundColor: string | undefined; foregroundColor: string | undefined;
text: string | undefined;
fontColor: string | undefined;
fontFamily: string | undefined;
}; };
const SVG_NS = { const SVG_NS = {
@@ -59,7 +56,7 @@ export class ColorOverridingIcon implements Icon {
newColors: () => Partial< newColors: () => Partial<
Pick< Pick<
Transformation, Transformation,
"backgroundColor" | "foregroundColor" | "fontColor" | "fontFamily" "backgroundColor" | "foregroundColor"
> >
>; >;
icon: Icon; icon: Icon;
@@ -70,7 +67,7 @@ export class ColorOverridingIcon implements Icon {
newColors: () => Partial< newColors: () => Partial<
Pick< Pick<
Transformation, Transformation,
"backgroundColor" | "foregroundColor" | "fontColor" | "fontFamily" "backgroundColor" | "foregroundColor"
> >
> >
) { ) {
@@ -97,9 +94,6 @@ export class SvgIcon implements Icon {
viewPortIncreasePercent: undefined, viewPortIncreasePercent: undefined,
backgroundColor: undefined, backgroundColor: undefined,
foregroundColor: undefined, foregroundColor: undefined,
text: undefined,
fontColor: undefined,
fontFamily: undefined,
} }
) { ) {
this.svg = svg; this.svg = svg;
@@ -143,31 +137,6 @@ export class SvgIcon implements Icon {
else path.attr({ fill: this.transformation.foregroundColor! }); else path.attr({ fill: this.transformation.foregroundColor! });
}); });
} }
if (this.transformation.text) {
const w = Math.abs(viewBox.minX) + Math.abs(viewBox.width);
const h = Math.abs(viewBox.minY) + Math.abs(viewBox.height);
const i = Math.floor(0.1 * w);
let attr: any = {
"font-size": `${Math.floor(h / 4)}`,
"font-weight": "bold",
};
if (this.transformation.fontFamily)
attr = { ...attr, "font-family": this.transformation.fontFamily };
if (this.transformation.fontColor)
attr = { ...attr, style: `fill:${this.transformation.fontColor}` };
const g = new Element(xml, "g");
g.attr(attr);
(xml.get("//svg:svg", SVG_NS) as Element).addChild(
g.addChild(
new Element(xml, "text")
.attr({
x: `${viewBox.minX + i}`,
y: `${viewBox.minY + Math.floor(0.8 * h)}`,
})
.text(this.transformation.text)
)
);
}
return xml.toString(); return xml.toString();
}; };
} }
@@ -186,7 +155,7 @@ export const makeFestive = (icon: Icon, clock: Clock = SystemClock): Icon => {
rule: (clock: Clock) => boolean, rule: (clock: Clock) => boolean,
colors: Pick< colors: Pick<
Transformation, Transformation,
"backgroundColor" | "foregroundColor" | "fontColor" "backgroundColor" | "foregroundColor"
> >
) => ) =>
new ColorOverridingIcon( new ColorOverridingIcon(
@@ -201,33 +170,29 @@ export const makeFestive = (icon: Icon, clock: Clock = SystemClock): Icon => {
rule: (clock: Clock) => boolean, rule: (clock: Clock) => boolean,
colors: Pick< colors: Pick<
Transformation, Transformation,
"backgroundColor" | "foregroundColor" | "fontColor" "backgroundColor" | "foregroundColor"
> >
) => (result = wrap(result, rule, colors)); ) => (result = wrap(result, rule, colors));
apply(isChristmas, { apply(isChristmas, {
backgroundColor: "green", backgroundColor: "green",
foregroundColor: "red", foregroundColor: "red",
fontColor: "white",
}); });
const randomHoliColors = _.shuffle([...HOLI_COLORS]); const randomHoliColors = _.shuffle([...HOLI_COLORS]);
apply(isHoli, { apply(isHoli, {
backgroundColor: randomHoliColors.pop(), backgroundColor: randomHoliColors.pop(),
foregroundColor: randomHoliColors.pop(), foregroundColor: randomHoliColors.pop(),
fontColor: randomHoliColors.pop(),
}); });
apply(isCNY, { apply(isCNY, {
backgroundColor: "red", backgroundColor: "red",
foregroundColor: "yellow", foregroundColor: "yellow",
fontColor: "crimson",
}); });
apply(isHalloween, { apply(isHalloween, {
backgroundColor: "orange", backgroundColor: "orange",
foregroundColor: "black", foregroundColor: "black",
fontColor: "orangered",
}); });
return result; return result;

View File

@@ -387,9 +387,6 @@ function server(
app.get("/icon/:type/size/:size", (req, res) => { app.get("/icon/:type/size/:size", (req, res) => {
const type = req.params["type"]!; const type = req.params["type"]!;
const size = req.params["size"]!; const size = req.params["size"]!;
const text: string | undefined = req.query.text
? (req.query.text as string)
: undefined;
if (!Object.keys(ICONS).includes(type)) { if (!Object.keys(ICONS).includes(type)) {
return res.status(404).send(); return res.status(404).send();
@@ -415,7 +412,7 @@ function server(
return Promise.resolve( return Promise.resolve(
makeFestive( makeFestive(
icon.with({ text, ...serverOpts.iconColors }), icon.with(serverOpts.iconColors),
clock clock
).toString() ).toString()
) )

View File

@@ -217,8 +217,7 @@ const genre = (bonobUrl: URLBuilder, genre: Genre) => ({
title: genre.name, title: genre.name,
albumArtURI: iconArtURI( albumArtURI: iconArtURI(
bonobUrl, bonobUrl,
iconForGenre(genre.name), iconForGenre(genre.name)
genre.name
).href(), ).href(),
}); });
@@ -254,12 +253,10 @@ export const defaultAlbumArtURI = (bonobUrl: URLBuilder, album: AlbumSummary) =>
export const iconArtURI = ( export const iconArtURI = (
bonobUrl: URLBuilder, bonobUrl: URLBuilder,
icon: ICON, icon: ICON
text: string | undefined = undefined
) => ) =>
bonobUrl.append({ bonobUrl.append({
pathname: `/icon/${icon}/size/legacy`, pathname: `/icon/${icon}/size/legacy`
searchParams: text ? { text } : {},
}); });
export const defaultArtistArtURI = ( export const defaultArtistArtURI = (

View File

@@ -169,68 +169,6 @@ describe("config", () => {
}); });
}); });
}); });
describe("fontColor", () => {
describe("when BONOB_ICON_FONT_COLOR is not specified", () => {
it(`should default to undefined`, () => {
expect(config().icons.fontColor).toEqual(undefined);
});
});
describe("when BONOB_ICON_FONT_COLOR is ''", () => {
it(`should default to undefined`, () => {
process.env["BONOB_ICON_FONT_COLOR"] = "";
expect(config().icons.fontColor).toEqual(undefined);
});
});
describe("when BONOB_ICON_FONT_COLOR is specified", () => {
it(`should use it`, () => {
process.env["BONOB_ICON_FONT_COLOR"] = "pink";
expect(config().icons.fontColor).toEqual("pink");
});
});
describe("when BONOB_ICON_FONT_COLOR is an invalid string", () => {
it(`should blow up`, () => {
process.env["BONOB_ICON_FONT_COLOR"] = "#dfasd";
expect(() => config()).toThrow(
"Invalid color specified for BONOB_ICON_FONT_COLOR"
);
});
});
});
describe("fontFamily", () => {
describe("when BONOB_ICON_FONT_FAMILY is not specified", () => {
it(`should default to undefined`, () => {
expect(config().icons.fontFamily).toEqual(undefined);
});
});
describe("when BONOB_ICON_FONT_FAMILY is ''", () => {
it(`should default to undefined`, () => {
process.env["BONOB_ICON_FONT_FAMILY"] = "";
expect(config().icons.fontFamily).toEqual(undefined);
});
});
describe("when BONOB_ICON_FONT_FAMILY is specified", () => {
it(`should use it`, () => {
process.env["BONOB_ICON_FONT_FAMILY"] = "helveta";
expect(config().icons.fontFamily).toEqual("helveta");
});
});
describe("when BONOB_ICON_FONT_FAMILY is an invalid string", () => {
it(`should blow up`, () => {
process.env["BONOB_ICON_FONT_FAMILY"] = "#dfasd";
expect(() => config()).toThrow(
"Invalid color specified for BONOB_ICON_FONT_FAMILY"
);
});
});
});
}); });
describe("secret", () => { describe("secret", () => {

View File

@@ -228,75 +228,6 @@ describe("SvgIcon", () => {
}); });
}); });
}); });
describe("with some text", () => {
describe("with no font color or style", () => {
describe("with no viewPort increase", () => {
it("should render the line", () => {
expect(
new SvgIcon(svgIcon24).with({ text: "hello" }).toString()
).toEqual(
xmlTidy(`<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="path1" />
<path d="path2" fill="none" stroke="#000"/>
<path d="path3" />
<g font-size="6" font-weight="bold">
<text x="2" y="19">hello</text>
</g>
</svg>
`)
);
});
});
describe("with a viewPort increase", () => {
it("should render the line", () => {
expect(
new SvgIcon(svgIcon24)
.with({ viewPortIncreasePercent: 50, text: "hello" })
.toString()
).toEqual(
xmlTidy(`<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-4 -4 32 32">
<path d="path1" />
<path d="path2" fill="none" stroke="#000"/>
<path d="path3" />
<g font-size="9" font-weight="bold">
<text x="-1" y="24">hello</text>
</g>
</svg>
`)
);
});
});
});
describe("with no font color and style", () => {
it("should render the line", () => {
expect(
new SvgIcon(svgIcon24)
.with({
text: "hello world",
fontColor: "red",
fontFamily: "helvetica",
})
.toString()
).toEqual(
xmlTidy(`<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="path1" />
<path d="path2" fill="none" stroke="#000"/>
<path d="path3" />
<g font-size="6" font-weight="bold" font-family="helvetica" style="fill:red">
<text x="2" y="19">hello world</text>
</g>
</svg>
`)
);
});
});
});
}); });
class DummyIcon implements Icon { class DummyIcon implements Icon {
@@ -315,8 +246,6 @@ describe("ColorOverridingIcon", () => {
const icon = new DummyIcon({ const icon = new DummyIcon({
backgroundColor: "black", backgroundColor: "black",
foregroundColor: "black", foregroundColor: "black",
fontColor: "black",
fontFamily: "plain",
}); });
describe("overriding some options", () => { describe("overriding some options", () => {
@@ -338,8 +267,6 @@ describe("ColorOverridingIcon", () => {
viewPortIncreasePercent: 99, viewPortIncreasePercent: 99,
backgroundColor: "blue", backgroundColor: "blue",
foregroundColor: "red", foregroundColor: "red",
fontColor: "black",
fontFamily: "plain",
}); });
}); });
}); });
@@ -350,8 +277,6 @@ describe("ColorOverridingIcon", () => {
new DummyIcon({ new DummyIcon({
backgroundColor: "blue", backgroundColor: "blue",
foregroundColor: "red", foregroundColor: "red",
fontColor: "black",
fontFamily: "plain",
}).toString() }).toString()
); );
}); });
@@ -365,8 +290,6 @@ describe("ColorOverridingIcon", () => {
() => ({ () => ({
backgroundColor: "blue", backgroundColor: "blue",
foregroundColor: "red", foregroundColor: "red",
fontColor: "pink",
fontFamily: "fancy",
}) })
); );
@@ -376,16 +299,12 @@ describe("ColorOverridingIcon", () => {
viewPortIncreasePercent: 99, viewPortIncreasePercent: 99,
backgroundColor: "shouldBeIgnored", backgroundColor: "shouldBeIgnored",
foregroundColor: "shouldBeIgnored", foregroundColor: "shouldBeIgnored",
fontColor: "shouldBeIgnored",
fontFamily: "shouldBeIgnored",
}) as DummyIcon; }) as DummyIcon;
expect(result.transformation).toEqual({ expect(result.transformation).toEqual({
viewPortIncreasePercent: 99, viewPortIncreasePercent: 99,
backgroundColor: "blue", backgroundColor: "blue",
foregroundColor: "red", foregroundColor: "red",
fontColor: "pink",
fontFamily: "fancy",
}); });
}); });
}); });
@@ -396,8 +315,6 @@ describe("ColorOverridingIcon", () => {
new DummyIcon({ new DummyIcon({
backgroundColor: "blue", backgroundColor: "blue",
foregroundColor: "red", foregroundColor: "red",
fontColor: "pink",
fontFamily: "fancy",
}).toString() }).toString()
); );
}); });
@@ -444,7 +361,6 @@ describe("makeFestive", () => {
const icon = new DummyIcon({ const icon = new DummyIcon({
backgroundColor: "black", backgroundColor: "black",
foregroundColor: "black", foregroundColor: "black",
fontColor: "black",
}); });
let now = dayjs(); let now = dayjs();
@@ -460,14 +376,12 @@ describe("makeFestive", () => {
viewPortIncreasePercent: 88, viewPortIncreasePercent: 88,
backgroundColor: "shouldBeUsed", backgroundColor: "shouldBeUsed",
foregroundColor: "shouldBeUsed", foregroundColor: "shouldBeUsed",
fontColor: "shouldBeUsed",
}) as DummyIcon; }) as DummyIcon;
expect(result.transformation).toEqual({ expect(result.transformation).toEqual({
viewPortIncreasePercent: 88, viewPortIncreasePercent: 88,
backgroundColor: "shouldBeUsed", backgroundColor: "shouldBeUsed",
foregroundColor: "shouldBeUsed", foregroundColor: "shouldBeUsed",
fontColor: "shouldBeUsed",
}); });
}); });
}); });
@@ -482,14 +396,12 @@ describe("makeFestive", () => {
viewPortIncreasePercent: 25, viewPortIncreasePercent: 25,
backgroundColor: "shouldNotBeUsed", backgroundColor: "shouldNotBeUsed",
foregroundColor: "shouldNotBeUsed", foregroundColor: "shouldNotBeUsed",
fontColor: "shouldNotBeUsed",
}) as DummyIcon; }) as DummyIcon;
expect(result.transformation).toEqual({ expect(result.transformation).toEqual({
viewPortIncreasePercent: 25, viewPortIncreasePercent: 25,
backgroundColor: "green", backgroundColor: "green",
foregroundColor: "red", foregroundColor: "red",
fontColor: "white",
}); });
}); });
}); });
@@ -504,14 +416,12 @@ describe("makeFestive", () => {
viewPortIncreasePercent: 12, viewPortIncreasePercent: 12,
backgroundColor: "shouldNotBeUsed", backgroundColor: "shouldNotBeUsed",
foregroundColor: "shouldNotBeUsed", foregroundColor: "shouldNotBeUsed",
fontColor: "shouldNotBeUsed",
}) as DummyIcon; }) as DummyIcon;
expect(result.transformation).toEqual({ expect(result.transformation).toEqual({
viewPortIncreasePercent: 12, viewPortIncreasePercent: 12,
backgroundColor: "orange", backgroundColor: "orange",
foregroundColor: "black", foregroundColor: "black",
fontColor: "orangered",
}); });
}); });
}); });
@@ -526,14 +436,12 @@ describe("makeFestive", () => {
viewPortIncreasePercent: 12, viewPortIncreasePercent: 12,
backgroundColor: "shouldNotBeUsed", backgroundColor: "shouldNotBeUsed",
foregroundColor: "shouldNotBeUsed", foregroundColor: "shouldNotBeUsed",
fontColor: "shouldNotBeUsed",
}) as DummyIcon; }) as DummyIcon;
expect(result.transformation).toEqual({ expect(result.transformation).toEqual({
viewPortIncreasePercent: 12, viewPortIncreasePercent: 12,
backgroundColor: "red", backgroundColor: "red",
foregroundColor: "yellow", foregroundColor: "yellow",
fontColor: "crimson",
}); });
}); });
}); });
@@ -548,7 +456,6 @@ describe("makeFestive", () => {
viewPortIncreasePercent: 12, viewPortIncreasePercent: 12,
backgroundColor: "shouldNotBeUsed", backgroundColor: "shouldNotBeUsed",
foregroundColor: "shouldNotBeUsed", foregroundColor: "shouldNotBeUsed",
fontColor: "shouldNotBeUsed",
}) as DummyIcon; }) as DummyIcon;
expect(result.transformation.viewPortIncreasePercent).toEqual(12); expect(result.transformation.viewPortIncreasePercent).toEqual(12);
@@ -558,15 +465,9 @@ describe("makeFestive", () => {
expect( expect(
HOLI_COLORS.includes(result.transformation.foregroundColor!) HOLI_COLORS.includes(result.transformation.foregroundColor!)
).toEqual(true); ).toEqual(true);
expect(HOLI_COLORS.includes(result.transformation.fontColor!)).toEqual(
true
);
expect(result.transformation.backgroundColor).not.toEqual( expect(result.transformation.backgroundColor).not.toEqual(
result.transformation.foregroundColor result.transformation.foregroundColor
); );
expect(result.transformation.backgroundColor).not.toEqual(
result.transformation.fontColor
);
}); });
}); });
}); });

View File

@@ -1636,16 +1636,6 @@ describe("server", () => {
expect(svg).toContain(`fill="brightpink"`); expect(svg).toContain(`fill="brightpink"`);
}); });
it("should return an icon with text if requested", async () => {
const response = await request(server(SystemClock)).get(
`/icon/${type}/size/180?text=foobar1000`
);
expect(response.status).toEqual(200);
const svg = Buffer.from(response.body).toString();
expect(svg).toContain(`foobar1000`);
});
it("should return a christmas icon on christmas day", async () => { it("should return a christmas icon on christmas day", async () => {
const response = await request( const response = await request(
server({ now: () => dayjs("2022/12/25") }) server({ now: () => dayjs("2022/12/25") })

View File

@@ -1021,7 +1021,6 @@ describe("api", () => {
albumArtURI: iconArtURI( albumArtURI: iconArtURI(
bonobUrl, bonobUrl,
iconForGenre(genre.name), iconForGenre(genre.name),
genre.name
).href(), ).href(),
})), })),
index: 0, index: 0,
@@ -1047,7 +1046,6 @@ describe("api", () => {
albumArtURI: iconArtURI( albumArtURI: iconArtURI(
bonobUrl, bonobUrl,
iconForGenre(genre.name), iconForGenre(genre.name),
genre.name
).href(), ).href(),
})), })),
index: 1, index: 1,