tangled
alpha
login
or
join now
bad-example.com
/
spacedust-utils
6
fork
atom
demos for spacedust
6
fork
atom
overview
issues
pulls
pipelines
basic bad notif style
bad-example.com
8 months ago
916137c7
297145eb
+87
-4
4 changed files
expand all
collapse all
unified
split
atproto-notifications
src
components
Feed.css
Feed.tsx
Notification.css
Notification.tsx
+6
-1
atproto-notifications/src/components/Feed.css
···
9
9
}
10
10
11
11
.feed-filter-type h4,
12
12
-
.feed-filter-secondary {
12
12
+
.feed-filter-secondary h4 {
13
13
margin: 0;
14
14
}
15
15
···
21
21
top: 0.1rem;
22
22
margin-right: 0.25rem;
23
23
}
24
24
+
25
25
+
.feed-notifications {
26
26
+
text-align: left;
27
27
+
margin: 2rem auto;
28
28
+
}
+6
-3
atproto-notifications/src/components/Feed.tsx
···
1
1
import { useEffect, useState } from 'react';
2
2
import { getNotifications, getSecondary } from '../db';
3
3
import { ButtonGroup } from './Buttons';
4
4
+
import { Notification } from './Notification';
4
5
import psl from 'psl';
5
6
import lexicons from 'lexicons';
6
7
···
138
139
/>
139
140
</div>
140
141
)}
141
141
-
{feed.map(([k, n]) => (
142
142
-
<p key={k}>{k}: {n.source} ({n.source_record}) <code>{JSON.stringify(n)}</code></p>
143
143
-
))}
142
142
+
<div className="feed-notifications">
143
143
+
{feed.map(([k, n]) => (
144
144
+
<Notification key={k} {...n} />
145
145
+
))}
146
146
+
</div>
144
147
</div>
145
148
);
146
149
}
+25
atproto-notifications/src/components/Notification.css
···
1
1
+
2
2
+
3
3
+
.notification {
4
4
+
padding: 0.75rem;
5
5
+
border: 0.5px solid hsla(0, 0%, 50%, 0.3);
6
6
+
border-width: 0.5px 0;
7
7
+
}
8
8
+
a.notification {
9
9
+
display: block;
10
10
+
font: inherit;
11
11
+
color: inherit;
12
12
+
}
13
13
+
a.notification:hover {
14
14
+
/*box-shadow: 0 42px 42px -42px inset #2c343c;*/
15
15
+
/*, 0 -42px 42px -42px inset #221828;*/
16
16
+
/*box-shadow: 0 42px 42px -42px inset #2c343c;*/
17
17
+
/*background: #221828;*/
18
18
+
background: #0b0d0f;
19
19
+
border-top-color: hsla(0, 0%, 100%, 0.3);
20
20
+
border-bottom-color: hsla(0, 0%, 0%, 0.3);
21
21
+
}
22
22
+
23
23
+
.handle {
24
24
+
color: skyblue;
25
25
+
}
+50
atproto-notifications/src/components/Notification.tsx
···
1
1
+
import psl from 'psl';
2
2
+
import lexicons from 'lexicons';
3
3
+
import { resolveDid } from '../atproto/resolve';
4
4
+
import { Fetch } from './Fetch';
5
5
+
6
6
+
import './Notification.css';
7
7
+
8
8
+
export function Notification({ app, group, source, source_record, source_did, subject }) {
9
9
+
10
10
+
// TODO: clean up / move this to lexicons package?
11
11
+
let title = source;
12
12
+
let icon;
13
13
+
let appName;
14
14
+
let appPrefix;
15
15
+
try {
16
16
+
appPrefix = app.split('.').toReversed().join('.');
17
17
+
} catch (e) {
18
18
+
console.error('getting top app failed', e);
19
19
+
}
20
20
+
const lex = lexicons[appPrefix];
21
21
+
icon = lex?.clients[0]?.icon;
22
22
+
const link = lex?.clients[0]?.notifications;
23
23
+
appName = lex?.name;
24
24
+
title = lex?.known_sources[source.slice(app.length + 1)] ?? source;
25
25
+
26
26
+
const contents = (
27
27
+
<>
28
28
+
{icon && (
29
29
+
<img className="app-icon" src={icon} title={appName ?? app} alt="" />
30
30
+
)}
31
31
+
{title} from
32
32
+
{' '}
33
33
+
{source_did ? (
34
34
+
<Fetch
35
35
+
using={resolveDid}
36
36
+
args={[source_did]}
37
37
+
ok={handle => <span className="handle">@{handle}</span>}
38
38
+
/>
39
39
+
) : (
40
40
+
source_record
41
41
+
)}
42
42
+
</>
43
43
+
);
44
44
+
45
45
+
return link
46
46
+
? <a className="notification" href={link} target="_blank">
47
47
+
{contents}
48
48
+
</a>
49
49
+
: <div className="notification">{contents}</div>;
50
50
+
}