Skip to content

Commit ac8ce07

Browse files
authored
Merge pull request #5 from solid/profile-colors
Profile colors
2 parents 6e2b8b4 + 5f5a213 commit ac8ce07

7 files changed

+173
-25
lines changed

package-lock.json

+88-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
"lit-html": "^1.3.0",
3535
"pane-registry": "^2.3.4",
3636
"rdflib": "^2.1.3",
37-
"solid-ui": "^2.3.8"
37+
"solid-ui": "^2.3.8",
38+
"validate-color": "^2.1.1"
3839
},
3940
"devDependencies": {
4041
"@babel/core": "^7.12.10",

src/ProfileCard.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { ProfilePresentation } from "./presenter";
1111

1212
const styles = {
1313
image: styleMap(fullWidth()),
14-
name: styleMap(heading()),
1514
intro: styleMap({ ...textGray(), ...textCenter() }),
1615
info: styleMap(padding()),
1716
};
@@ -21,15 +20,23 @@ export const ProfileCard = ({
2120
imageSrc,
2221
introduction,
2322
location,
24-
}: ProfilePresentation) => html`
25-
${Image(imageSrc, name)}
26-
<div style=${styles.info}>
27-
<h3 style=${styles.name}>${name}</h3>
28-
<div style=${styles.intro}>
29-
${Line(introduction)} ${Line(location, "🌐")}
23+
highlightColor,
24+
}: ProfilePresentation) => {
25+
const nameStyle = styleMap({
26+
...heading(),
27+
"text-decoration": "underline",
28+
"text-decoration-color": highlightColor,
29+
});
30+
return html`
31+
${Image(imageSrc, name)}
32+
<div style=${styles.info}>
33+
<h3 style=${nameStyle}>${name}</h3>
34+
<div style=${styles.intro}>
35+
${Line(introduction)} ${Line(location, "🌐")}
36+
</div>
3037
</div>
31-
</div>
32-
`;
38+
`;
39+
};
3340

3441
const Line = (value, prefix = nothing) =>
3542
value ? html`<p>${prefix} ${value}</p>` : nothing;

src/ProfileView.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@ import { DataBrowserContext } from "pane-registry";
77
import { FriendList } from "./FriendList";
88
import { presentProfile } from "./presenter";
99

10-
const styles = {
11-
grid: styleMap({ ...responsiveGrid(), ...paddingSmall() }),
12-
card: styleMap(card()),
13-
};
14-
1510
export const ProfileView = (
1611
subject: NamedNode,
1712
context: DataBrowserContext
1813
) => {
1914
const profile = presentProfile(subject, context.session.store);
2015

16+
const styles = {
17+
grid: styleMap({
18+
...responsiveGrid(),
19+
...paddingSmall(),
20+
background: `radial-gradient(circle, ${profile.backgroundColor} 80%, ${profile.highlightColor} 100%)`,
21+
}),
22+
card: styleMap(card()),
23+
};
24+
2125
return html`
2226
<div style="${styles.grid}">
2327
<div>

src/baseStyles.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const responsiveGrid = () => ({
77
});
88

99
export const card = () => ({
10+
backgroundColor: "white",
1011
borderRadius: "4px",
1112
boxShadow: "0 1px 5px rgba(0,0,0,0.2)",
1213
padding: "0",

src/presenter.spec.ts

+25
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,29 @@ describe("presenter", () => {
7878
const result = presentProfile(jane, store);
7979
expect(result.location).toBe("Hamburg, Germany");
8080
});
81+
82+
describe("coloring", () => {
83+
it("presents default colors", () => {
84+
const result = presentProfile(jane, store);
85+
expect(result.backgroundColor).toBe("#eee");
86+
expect(result.highlightColor).toBe("#090");
87+
});
88+
it("uses background color from profile settings", () => {
89+
store.add(jane, ns.solid("profileBackgroundColor"), "#123456", doc);
90+
const { backgroundColor } = presentProfile(jane, store);
91+
expect(backgroundColor).toBe("#123456");
92+
});
93+
it("uses highlight color from profile settings", () => {
94+
store.add(jane, ns.solid("profileHighlightColor"), "#987654", doc);
95+
const { highlightColor } = presentProfile(jane, store);
96+
expect(highlightColor).toBe("#987654");
97+
});
98+
it("presents default colors if settings are messed up", () => {
99+
store.add(jane, ns.solid("profileBackgroundColor"), "foobar", doc);
100+
store.add(jane, ns.solid("profileHighlightColor"), "42", doc);
101+
const result = presentProfile(jane, store);
102+
expect(result.backgroundColor).toBe("#eee");
103+
expect(result.highlightColor).toBe("#090");
104+
});
105+
});
81106
});

src/presenter.ts

+32
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import { IndexedFormula, NamedNode } from "rdflib";
22
import { ns, utils } from "solid-ui";
33
import { findImage } from "solid-ui/lib/widgets/buttons";
44
import Node from "rdflib/src/node-internal";
5+
import { validateHTMLColorHex } from "validate-color";
56

67
export interface ProfilePresentation {
78
name: string;
89
imageSrc?: string;
910
introduction?: string;
1011
location?: string;
12+
backgroundColor: string;
13+
highlightColor: string;
1114
}
1215

1316
export const presentProfile = (
@@ -28,11 +31,16 @@ export const presentProfile = (
2831
address != null
2932
? store.anyValue(address as NamedNode, ns.vcard("locality"))
3033
: null;
34+
35+
const { backgroundColor, highlightColor } = getColors(subject, store);
36+
3137
return {
3238
name,
3339
imageSrc,
3440
introduction: formatIntroduction(role, orgName),
3541
location: formatLocation(countryName, locality),
42+
backgroundColor,
43+
highlightColor,
3644
};
3745
};
3846

@@ -45,3 +53,27 @@ function formatLocation(countryName: string | void, locality: string | void) {
4553
function formatIntroduction(role: string | void, orgName: string | void) {
4654
return role && orgName ? `${role} at ${orgName}` : orgName || role || null;
4755
}
56+
57+
function getColors(subject: NamedNode, store: IndexedFormula) {
58+
const backgroundColor = store.anyValue(
59+
subject,
60+
ns.solid("profileBackgroundColor"),
61+
null,
62+
subject.doc()
63+
);
64+
65+
const highlightColor = store.anyValue(
66+
subject,
67+
ns.solid("profileHighlightColor"),
68+
null,
69+
subject.doc()
70+
);
71+
return {
72+
backgroundColor: validColorOrDefault(backgroundColor, "#eee"),
73+
highlightColor: validColorOrDefault(highlightColor, "#090"),
74+
};
75+
}
76+
77+
function validColorOrDefault(color: string | void, fallback: string) {
78+
return color && validateHTMLColorHex(color) ? color : fallback;
79+
}

0 commit comments

Comments
 (0)