Skip to content

Commit 0935103

Browse files
committed
hashtags
1 parent 1d57e53 commit 0935103

File tree

9 files changed

+73
-13
lines changed

9 files changed

+73
-13
lines changed

src/lib/lib.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,13 @@ export function searchSessions(
777777
}
778778
}
779779

780+
export function getHashTags(head: t.SessionHead): string[] {
781+
const regexp = /(?:^|\s)(#[a-zA-Z0-9_-]+)(?=$|[^a-zA-Z0-9_-])/g;
782+
const titleTagsIt = head.title.matchAll(regexp);
783+
const descTagsIt = head.description.matchAll(regexp);
784+
return [...titleTagsIt, ...descTagsIt].map(m => m[1]);
785+
}
786+
780787
// export function limitRecentSessions(sessions: t.SessionUIListing[], limit: number): t.SessionUIListing[] {
781788
// let res = [];
782789
// let count = 0;

src/view/base.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ body.vscode-light {
5555
/* --ranged-track-border-active: #007acc; */
5656

5757
--text-weak: #666;
58+
--text-weak-2: #8f8f8f;
5859
--background-secondary: #e7e7e7;
5960

6061
--editor-track-color: #666;
@@ -93,6 +94,7 @@ body.vscode-dark {
9394
/* --ranged-track-border-active: #007acc; */
9495

9596
--text-weak: #aaa;
97+
--text-weak-2: #939393;
9698
--background-secondary: #181818;
9799

98100
--editor-track-color: #aaa;
@@ -278,3 +280,7 @@ button {
278280
.fa-solid {
279281
line-height: 1.2 !important;
280282
}
283+
284+
.no-select {
285+
user-select: none;
286+
}

src/view/player.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export default class Player extends React.Component<Props> {
230230
{head.isClip && clock === 0 && <ClipBanner />}
231231
<video id="guide-video" />
232232
</div>
233-
<SessionHead className="subsection subsection_spaced" head={head} withAuthor />
233+
<SessionHead className="subsection subsection_spaced" head={head} />
234234
<SessionDescription
235235
className="subsection"
236236
head={head}

src/view/recorder.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ class DetailsView extends React.PureComponent<DetailsViewProps> {
281281
resize="vertical"
282282
value={p.description}
283283
onInput={this.descriptionChanged}
284-
placeholder="What is this session about?"
284+
// Don't change the placeholder={'...'} to placeholder="" or the new line character won't be interpreted
285+
placeholder={'What is this session about?\n\n#C #JavaScript #OpenGL'}
285286
>
286287
Description
287288
</VSCodeTextArea>

src/view/section.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
font-size: 0.9rem;
6363
color: var(--text-weak);
6464
text-align: center;
65-
letter-spacing: 2px;
65+
letter-spacing: 1px;
6666
}
6767
}
6868
}

src/view/session_description.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
> .body {
2929
margin-top: var(--spacing-small);
3030

31+
& p.tags {
32+
font-size: 0.8em;
33+
color: var(--text-weak);
34+
}
35+
3136
& a.expand {
3237
}
3338
}

src/view/session_description.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { cn } from './misc.js';
55
import TextToParagraphs from './text_to_paragraphs.jsx';
66
import React, { useState } from 'react';
77
import { VSCodeButton } from '@vscode/webview-ui-toolkit/react/index.js';
8+
import _ from 'lodash';
89

910
const EXPAND_THRESHOLD = 300;
1011

@@ -24,6 +25,9 @@ export default function SessionDescription(props: Props) {
2425
const description =
2526
expandable && !expanded ? head.description.substring(0, EXPAND_THRESHOLD) + '...' : head.description;
2627

28+
const tags = lib.getHashTags(head);
29+
const tagsStr = _.truncate(_.take(tags, 6).join(' '), { length: 60 });
30+
2731
function toggleExpansion(e: React.MouseEvent) {
2832
e.preventDefault();
2933
e.stopPropagation();
@@ -58,6 +62,7 @@ export default function SessionDescription(props: Props) {
5862
</>
5963
</div>
6064
<div className="body">
65+
<p className="tags">{tagsStr}</p>
6166
<TextToParagraphs text={description} />
6267
{expandable && (
6368
<a className="expand" href="#" onClick={toggleExpansion}>

src/view/session_head.css

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@
109109
.title {
110110
font-weight: bold;
111111
font-size: 1em;
112+
113+
.tags {
114+
font-size: 0.8em;
115+
color: var(--text-weak-2);
116+
}
112117
}
113118

114119
.cover + .title {
@@ -178,10 +183,16 @@
178183
display: flex;
179184
flex-direction: column;
180185
justify-content: center;
186+
width: 100%; /* to allow text-overflow: ellipsis of author/handle */
187+
overflow: hidden;
181188

182189
.title {
183190
font-weight: bold;
184-
/* font-size: 1.1em; */
191+
192+
/* .tags { */
193+
/* font-size: 0.8em; */
194+
/* color: var(--text-weak-2); */
195+
/* } */
185196
}
186197

187198
.description {
@@ -202,6 +213,17 @@
202213
.footer-item {
203214
/* white-space: nowrap; */
204215

216+
&.author {
217+
white-space: nowrap;
218+
text-overflow: ellipsis;
219+
overflow: hidden;
220+
221+
.handle {
222+
/* font-size: 0.9em; */
223+
/* color: var(--text-weak); */
224+
}
225+
}
226+
205227
&:first-child {
206228
/* min-width: 80px; */
207229
flex: 1;

src/view/session_head.tsx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,27 @@ import ClipBanner from './clip_banner.jsx';
1414
export type SessionHeadProps = {
1515
className?: string;
1616
head: t.SessionHead;
17-
withAuthor?: boolean;
1817
};
1918

20-
export function SessionHead({ className, withAuthor, head }: SessionHeadProps) {
19+
export function SessionHead({ className, head }: SessionHeadProps) {
20+
// const tags = lib.getHashTags(head);
21+
// const tagsStr = _.truncate(_.take(tags, 6).join(' '), { length: 60 });
22+
2123
return (
2224
<WithAvatar className={cn('session-head', className)} username={head.author}>
23-
<div className="title">{head.title || 'Untitled'}</div>
24-
{withAuthor && (
25-
<div className="footer">
26-
<span className="footer-item author">{head.author || 'anonymous'}</span>
27-
</div>
28-
)}
25+
<div className="title">
26+
{head.title || 'Untitled'}
27+
{/* <span className="tags">{tagsStr}</span>*/}
28+
</div>
29+
<div className="footer">
30+
<span className="footer-item author" title={`@${head.author || 'anonymous'}/${head.handle}`}>
31+
{head.author || 'anonymous'}
32+
<span className="handle">
33+
<span className="no-select"> </span>/<span className="no-select"> </span>
34+
{head.handle}
35+
</span>
36+
</span>
37+
</div>
2938
</WithAvatar>
3039
);
3140
}
@@ -82,6 +91,9 @@ export function SessionListing(props: SessionListingProps) {
8291
},
8392
]);
8493

94+
const tags = lib.getHashTags(head);
95+
const tagsStr = _.truncate(_.take(tags, 3).join(' '), { length: 30 });
96+
8597
return (
8698
<div className={cn('session-listing', props.className)} onClick={() => props.onClick(head.id)} tabIndex={0}>
8799
<div className="cover-container">
@@ -95,7 +107,9 @@ export function SessionListing(props: SessionListingProps) {
95107
) : null}
96108
</div>
97109
<WithAvatar username={head.author} className="caption" small>
98-
<div className="title">{head.title || 'Untitled'}</div>
110+
<div className="title">
111+
{head.title || 'Untitled'} <span className="tags">{tagsStr}</span>
112+
</div>
99113
{/*head.description && (
100114
<div className="description">
101115
<TextToParagraphs text={head.description} />

0 commit comments

Comments
 (0)