@rmdes/indiekit-endpoint-microsub 1.0.45 → 1.0.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/styles.css +328 -328
- package/package.json +1 -1
- package/views/actor.njk +38 -41
- package/views/channel.njk +22 -22
- package/views/compose.njk +7 -7
- package/views/deck-settings.njk +4 -4
- package/views/deck.njk +11 -11
- package/views/feed-edit.njk +12 -12
- package/views/feeds.njk +18 -19
- package/views/item.njk +23 -24
- package/views/partials/actions.njk +6 -6
- package/views/partials/breadcrumbs.njk +5 -5
- package/views/partials/item-card-compact.njk +12 -13
- package/views/partials/item-card.njk +50 -70
- package/views/partials/timeline.njk +1 -1
- package/views/partials/view-switcher.njk +4 -4
- package/views/reader.njk +7 -7
- package/views/search.njk +16 -16
- package/views/settings.njk +1 -1
- package/views/timeline.njk +30 -30
package/views/feeds.njk
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{% extends "layouts/reader.njk" %}
|
|
2
2
|
|
|
3
3
|
{% block reader %}
|
|
4
|
-
<div class="feeds">
|
|
5
|
-
<header class="feeds__header">
|
|
4
|
+
<div class="ms-feeds">
|
|
5
|
+
<header class="ms-feeds__header">
|
|
6
6
|
<a href="{{ baseUrl }}/channels/{{ channel.uid }}" class="back-link">
|
|
7
7
|
{{ icon("previous") }} {{ channel.name }}
|
|
8
8
|
</a>
|
|
@@ -11,27 +11,26 @@
|
|
|
11
11
|
<h2>{{ __("microsub.feeds.title") }}</h2>
|
|
12
12
|
|
|
13
13
|
{% if error %}
|
|
14
|
-
<div class="notice notice--error" role="alert">
|
|
14
|
+
<div class="ms-notice ms-notice--error" role="alert">
|
|
15
15
|
{{ error }}
|
|
16
16
|
</div>
|
|
17
17
|
{% endif %}
|
|
18
18
|
|
|
19
19
|
{% if feeds.length > 0 %}
|
|
20
|
-
<div class="feeds__list">
|
|
20
|
+
<div class="ms-feeds__list">
|
|
21
21
|
{% for feed in feeds %}
|
|
22
|
-
<div class="feeds__item{% if feed.status == 'error' %} feeds__item--error{% endif %}">
|
|
23
|
-
<div class="feeds__info">
|
|
22
|
+
<div class="ms-feeds__item{% if feed.status == 'error' %} ms-feeds__item--error{% endif %}">
|
|
23
|
+
<div class="ms-feeds__info">
|
|
24
24
|
{% if feed.photo %}
|
|
25
25
|
<img src="{{ feed.photo }}"
|
|
26
26
|
alt=""
|
|
27
|
-
class="feeds__photo"
|
|
27
|
+
class="ms-feeds__photo"
|
|
28
28
|
width="48"
|
|
29
29
|
height="48"
|
|
30
|
-
loading="lazy"
|
|
31
|
-
onerror="this.style.display='none'">
|
|
30
|
+
loading="lazy">
|
|
32
31
|
{% endif %}
|
|
33
|
-
<div class="feeds__details">
|
|
34
|
-
<span class="feeds__name">
|
|
32
|
+
<div class="ms-feeds__details">
|
|
33
|
+
<span class="ms-feeds__name">
|
|
35
34
|
{{ feed.title or feed.url }}
|
|
36
35
|
{% if feed.feedType %}
|
|
37
36
|
<span class="badge badge--offset badge--small" title="Feed format">{{ feed.feedType | upper }}</span>
|
|
@@ -42,21 +41,21 @@
|
|
|
42
41
|
<span class="badge badge--green">Active</span>
|
|
43
42
|
{% endif %}
|
|
44
43
|
</span>
|
|
45
|
-
<a href="{{ feed.url }}" class="feeds__url" target="_blank" rel="noopener">
|
|
44
|
+
<a href="{{ feed.url }}" class="ms-feeds__url" target="_blank" rel="noopener">
|
|
46
45
|
{{ feed.url | replace("https://", "") | replace("http://", "") }}
|
|
47
46
|
</a>
|
|
48
47
|
{% if feed.lastError %}
|
|
49
|
-
<span class="feeds__error">{{ feed.lastError }}</span>
|
|
48
|
+
<span class="ms-feeds__error">{{ feed.lastError }}</span>
|
|
50
49
|
{% endif %}
|
|
51
50
|
{% if feed.consecutiveErrors > 0 %}
|
|
52
|
-
<span class="feeds__error-count">{{ feed.consecutiveErrors }} consecutive errors</span>
|
|
51
|
+
<span class="ms-feeds__error-count">{{ feed.consecutiveErrors }} consecutive errors</span>
|
|
53
52
|
{% endif %}
|
|
54
53
|
{% if feed.lastSuccessAt %}
|
|
55
|
-
<span class="feeds__meta">Last success: {{ feed.lastSuccessAt }}</span>
|
|
54
|
+
<span class="ms-feeds__meta">Last success: {{ feed.lastSuccessAt }}</span>
|
|
56
55
|
{% endif %}
|
|
57
56
|
</div>
|
|
58
57
|
</div>
|
|
59
|
-
<div class="feeds__actions">
|
|
58
|
+
<div class="ms-feeds__actions">
|
|
60
59
|
<a href="{{ baseUrl }}/channels/{{ channel.uid }}/feeds/{{ feed._id }}/edit"
|
|
61
60
|
class="button button--secondary button--small"
|
|
62
61
|
title="Edit feed URL">
|
|
@@ -83,15 +82,15 @@
|
|
|
83
82
|
{% endfor %}
|
|
84
83
|
</div>
|
|
85
84
|
{% else %}
|
|
86
|
-
<div class="reader__empty">
|
|
85
|
+
<div class="ms-reader__empty">
|
|
87
86
|
{{ icon("syndicate") }}
|
|
88
87
|
<p>{{ __("microsub.feeds.empty") }}</p>
|
|
89
88
|
</div>
|
|
90
89
|
{% endif %}
|
|
91
90
|
|
|
92
|
-
<div class="feeds__add">
|
|
91
|
+
<div class="ms-feeds__add">
|
|
93
92
|
<h3>{{ __("microsub.feeds.follow") }}</h3>
|
|
94
|
-
<form method="post" action="{{ baseUrl }}/channels/{{ channel.uid }}/feeds" class="feeds__form">
|
|
93
|
+
<form method="post" action="{{ baseUrl }}/channels/{{ channel.uid }}/feeds" class="ms-feeds__form">
|
|
95
94
|
{{ input({
|
|
96
95
|
id: "url",
|
|
97
96
|
name: "url",
|
package/views/item.njk
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
{% extends "layouts/reader.njk" %}
|
|
2
2
|
|
|
3
3
|
{% block reader %}
|
|
4
|
-
<article class="item">
|
|
4
|
+
<article class="ms-item">
|
|
5
5
|
<a href="{{ backUrl or (baseUrl + '/channels') }}" class="back-link">
|
|
6
6
|
{{ icon("previous") }} {{ __("Back") }}
|
|
7
7
|
</a>
|
|
8
8
|
|
|
9
9
|
{% if item.author %}
|
|
10
|
-
<header class="item__author">
|
|
10
|
+
<header class="ms-item__author">
|
|
11
11
|
{% if item.author.photo %}
|
|
12
12
|
<img src="{{ item.author.photo }}"
|
|
13
13
|
alt=""
|
|
14
|
-
class="item__author-photo"
|
|
14
|
+
class="ms-item__author-photo"
|
|
15
15
|
width="48"
|
|
16
16
|
height="48"
|
|
17
|
-
loading="lazy"
|
|
18
|
-
onerror="this.style.display='none'">
|
|
17
|
+
loading="lazy">
|
|
19
18
|
{% endif %}
|
|
20
|
-
<div class="item__author-info">
|
|
21
|
-
<span class="item__author-name">
|
|
19
|
+
<div class="ms-item__author-info">
|
|
20
|
+
<span class="ms-item__author-name">
|
|
22
21
|
{% if item.author.url %}
|
|
23
22
|
<a href="{{ item.author.url }}" target="_blank" rel="noopener">{{ item.author.name or item.author.url }}</a>
|
|
24
23
|
{% else %}
|
|
@@ -26,7 +25,7 @@
|
|
|
26
25
|
{% endif %}
|
|
27
26
|
</span>
|
|
28
27
|
{% if item.published %}
|
|
29
|
-
<time datetime="{{ item.published }}" class="item__date">
|
|
28
|
+
<time datetime="{{ item.published }}" class="ms-item__date">
|
|
30
29
|
{{ item.published | date("PPPp", { locale: locale, timeZone: application.timeZone }) }}
|
|
31
30
|
</time>
|
|
32
31
|
{% endif %}
|
|
@@ -36,9 +35,9 @@
|
|
|
36
35
|
|
|
37
36
|
{# Context for interactions #}
|
|
38
37
|
{% if item["in-reply-to"] or item["like-of"] or item["repost-of"] or item["bookmark-of"] %}
|
|
39
|
-
<div class="item__context">
|
|
38
|
+
<div class="ms-item__context">
|
|
40
39
|
{% if item["in-reply-to"] and item["in-reply-to"].length > 0 %}
|
|
41
|
-
<p class="item__context-label">
|
|
40
|
+
<p class="ms-item__context-label">
|
|
42
41
|
{{ icon("reply") }} {{ __("Reply to") }}:
|
|
43
42
|
<a href="{{ item['in-reply-to'][0] }}" target="_blank" rel="noopener">
|
|
44
43
|
{{ item["in-reply-to"][0] | replace("https://", "") | replace("http://", "") }}
|
|
@@ -46,7 +45,7 @@
|
|
|
46
45
|
</p>
|
|
47
46
|
{% endif %}
|
|
48
47
|
{% if item["like-of"] and item["like-of"].length > 0 %}
|
|
49
|
-
<p class="item__context-label">
|
|
48
|
+
<p class="ms-item__context-label">
|
|
50
49
|
{{ icon("like") }} {{ __("Liked") }}:
|
|
51
50
|
<a href="{{ item['like-of'][0] }}" target="_blank" rel="noopener">
|
|
52
51
|
{{ item["like-of"][0] | replace("https://", "") | replace("http://", "") }}
|
|
@@ -54,7 +53,7 @@
|
|
|
54
53
|
</p>
|
|
55
54
|
{% endif %}
|
|
56
55
|
{% if item["repost-of"] and item["repost-of"].length > 0 %}
|
|
57
|
-
<p class="item__context-label">
|
|
56
|
+
<p class="ms-item__context-label">
|
|
58
57
|
{{ icon("repost") }} {{ __("Reposted") }}:
|
|
59
58
|
<a href="{{ item['repost-of'][0] }}" target="_blank" rel="noopener">
|
|
60
59
|
{{ item["repost-of"][0] | replace("https://", "") | replace("http://", "") }}
|
|
@@ -62,7 +61,7 @@
|
|
|
62
61
|
</p>
|
|
63
62
|
{% endif %}
|
|
64
63
|
{% if item["bookmark-of"] and item["bookmark-of"].length > 0 %}
|
|
65
|
-
<p class="item__context-label">
|
|
64
|
+
<p class="ms-item__context-label">
|
|
66
65
|
{{ icon("bookmark") }} {{ __("Bookmarked") }}:
|
|
67
66
|
<a href="{{ item['bookmark-of'][0] }}" target="_blank" rel="noopener">
|
|
68
67
|
{{ item["bookmark-of"][0] | replace("https://", "") | replace("http://", "") }}
|
|
@@ -73,11 +72,11 @@
|
|
|
73
72
|
{% endif %}
|
|
74
73
|
|
|
75
74
|
{% if item.name %}
|
|
76
|
-
<h2 class="item__title">{{ item.name }}</h2>
|
|
75
|
+
<h2 class="ms-item__title">{{ item.name }}</h2>
|
|
77
76
|
{% endif %}
|
|
78
77
|
|
|
79
78
|
{% if item.content %}
|
|
80
|
-
<div class="item__content prose">
|
|
79
|
+
<div class="ms-item__content prose">
|
|
81
80
|
{% if item.content.html %}
|
|
82
81
|
{{ item.content.html | safe }}
|
|
83
82
|
{% else %}
|
|
@@ -88,19 +87,19 @@
|
|
|
88
87
|
|
|
89
88
|
{# Categories #}
|
|
90
89
|
{% if item.category and item.category.length > 0 %}
|
|
91
|
-
<div class="item-card__categories">
|
|
90
|
+
<div class="ms-item-card__categories">
|
|
92
91
|
{% for cat in item.category %}
|
|
93
|
-
<span class="item-card__category">#{{ cat | replace("#", "") }}</span>
|
|
92
|
+
<span class="ms-item-card__category">#{{ cat | replace("#", "") }}</span>
|
|
94
93
|
{% endfor %}
|
|
95
94
|
</div>
|
|
96
95
|
{% endif %}
|
|
97
96
|
|
|
98
97
|
{# Photos #}
|
|
99
98
|
{% if item.photo and item.photo.length > 0 %}
|
|
100
|
-
<div class="item__photos">
|
|
99
|
+
<div class="ms-item__photos">
|
|
101
100
|
{% for photo in item.photo %}
|
|
102
101
|
<a href="{{ photo }}" target="_blank" rel="noopener">
|
|
103
|
-
<img src="{{ photo }}" alt="" class="item__photo" loading="lazy">
|
|
102
|
+
<img src="{{ photo }}" alt="" class="ms-item__photo" loading="lazy">
|
|
104
103
|
</a>
|
|
105
104
|
{% endfor %}
|
|
106
105
|
</div>
|
|
@@ -108,7 +107,7 @@
|
|
|
108
107
|
|
|
109
108
|
{# Video #}
|
|
110
109
|
{% if item.video and item.video.length > 0 %}
|
|
111
|
-
<div class="item__media">
|
|
110
|
+
<div class="ms-item__media">
|
|
112
111
|
{% for video in item.video %}
|
|
113
112
|
<video src="{{ video }}"
|
|
114
113
|
controls
|
|
@@ -121,14 +120,14 @@
|
|
|
121
120
|
|
|
122
121
|
{# Audio #}
|
|
123
122
|
{% if item.audio and item.audio.length > 0 %}
|
|
124
|
-
<div class="item__media">
|
|
123
|
+
<div class="ms-item__media">
|
|
125
124
|
{% for audio in item.audio %}
|
|
126
125
|
<audio src="{{ audio }}" controls preload="metadata"></audio>
|
|
127
126
|
{% endfor %}
|
|
128
127
|
</div>
|
|
129
128
|
{% endif %}
|
|
130
129
|
|
|
131
|
-
<footer class="item__actions">
|
|
130
|
+
<footer class="ms-item__actions">
|
|
132
131
|
{% if item.url %}
|
|
133
132
|
<a href="{{ item.url }}" class="button button--secondary button--small" target="_blank" rel="noopener">
|
|
134
133
|
{{ icon("external") }} {{ __("microsub.item.viewOriginal") }}
|
|
@@ -148,7 +147,7 @@
|
|
|
148
147
|
</a>
|
|
149
148
|
{% if not item._is_read %}
|
|
150
149
|
<button type="button"
|
|
151
|
-
class="button button--secondary button--small item__mark-read"
|
|
150
|
+
class="button button--secondary button--small ms-item__mark-read"
|
|
152
151
|
data-item-id="{{ item._id }}"
|
|
153
152
|
data-channel="{{ channel.uid }}">
|
|
154
153
|
{{ icon("checkboxChecked") }} {{ __("microsub.timeline.markRead") }}
|
|
@@ -159,7 +158,7 @@
|
|
|
159
158
|
|
|
160
159
|
<script type="module">
|
|
161
160
|
// Handle mark-read button
|
|
162
|
-
const markReadBtn = document.querySelector('.item__mark-read');
|
|
161
|
+
const markReadBtn = document.querySelector('.ms-item__mark-read');
|
|
163
162
|
if (markReadBtn) {
|
|
164
163
|
markReadBtn.addEventListener('click', async () => {
|
|
165
164
|
const itemId = markReadBtn.dataset.itemId;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{# Item action buttons #}
|
|
2
|
-
<div class="item-actions">
|
|
3
|
-
<a href="{{ baseUrl }}/compose?replyTo={{ itemUrl | urlencode }}" class="item-actions__button" title="{{ __('microsub.item.reply') }}">
|
|
2
|
+
<div class="ms-item-actions">
|
|
3
|
+
<a href="{{ baseUrl }}/compose?replyTo={{ itemUrl | urlencode }}" class="ms-item-actions__button" title="{{ __('microsub.item.reply') }}">
|
|
4
4
|
{{ icon("reply") }}
|
|
5
5
|
</a>
|
|
6
|
-
<a href="{{ baseUrl }}/compose?likeOf={{ itemUrl | urlencode }}" class="item-actions__button" title="{{ __('microsub.item.like') }}">
|
|
6
|
+
<a href="{{ baseUrl }}/compose?likeOf={{ itemUrl | urlencode }}" class="ms-item-actions__button" title="{{ __('microsub.item.like') }}">
|
|
7
7
|
{{ icon("like") }}
|
|
8
8
|
</a>
|
|
9
|
-
<a href="{{ baseUrl }}/compose?repostOf={{ itemUrl | urlencode }}" class="item-actions__button" title="{{ __('microsub.item.repost') }}">
|
|
9
|
+
<a href="{{ baseUrl }}/compose?repostOf={{ itemUrl | urlencode }}" class="ms-item-actions__button" title="{{ __('microsub.item.repost') }}">
|
|
10
10
|
{{ icon("repost") }}
|
|
11
11
|
</a>
|
|
12
|
-
<a href="{{ baseUrl }}/compose?bookmarkOf={{ itemUrl | urlencode }}" class="item-actions__button" title="{{ __('microsub.item.bookmark') }}">
|
|
12
|
+
<a href="{{ baseUrl }}/compose?bookmarkOf={{ itemUrl | urlencode }}" class="ms-item-actions__button" title="{{ __('microsub.item.bookmark') }}">
|
|
13
13
|
{{ icon("bookmark") }}
|
|
14
14
|
</a>
|
|
15
|
-
<a href="{{ itemUrl }}" class="item-actions__button" target="_blank" rel="noopener" title="{{ __('microsub.item.viewOriginal') }}">
|
|
15
|
+
<a href="{{ itemUrl }}" class="ms-item-actions__button" target="_blank" rel="noopener" title="{{ __('microsub.item.viewOriginal') }}">
|
|
16
16
|
{{ icon("public") }}
|
|
17
17
|
</a>
|
|
18
18
|
</div>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{# Breadcrumb navigation #}
|
|
2
2
|
{% if breadcrumbs and breadcrumbs.length > 0 %}
|
|
3
|
-
<nav class="breadcrumbs" aria-label="Breadcrumb">
|
|
4
|
-
<ol class="breadcrumbs__list">
|
|
3
|
+
<nav class="ms-breadcrumbs" aria-label="Breadcrumb">
|
|
4
|
+
<ol class="ms-breadcrumbs__list">
|
|
5
5
|
{% for crumb in breadcrumbs %}
|
|
6
|
-
<li class="breadcrumbs__item">
|
|
6
|
+
<li class="ms-breadcrumbs__item">
|
|
7
7
|
{% if crumb.href %}
|
|
8
|
-
<a href="{{ crumb.href }}" class="breadcrumbs__link">{{ crumb.text }}</a>
|
|
8
|
+
<a href="{{ crumb.href }}" class="ms-breadcrumbs__link">{{ crumb.text }}</a>
|
|
9
9
|
{% else %}
|
|
10
|
-
<span class="breadcrumbs__current" aria-current="page">{{ crumb.text }}</span>
|
|
10
|
+
<span class="ms-breadcrumbs__current" aria-current="page">{{ crumb.text }}</span>
|
|
11
11
|
{% endif %}
|
|
12
12
|
</li>
|
|
13
13
|
{% endfor %}
|
|
@@ -1,37 +1,36 @@
|
|
|
1
1
|
{# Compact item card for deck columns #}
|
|
2
|
-
<article class="item-card-compact{% if item._is_read %} item-card-compact--read{% endif %}"
|
|
2
|
+
<article class="ms-item-card-compact{% if item._is_read %} ms-item-card-compact--read{% endif %}"
|
|
3
3
|
data-item-id="{{ item._id }}">
|
|
4
|
-
<a href="{{ readerBaseUrl }}/item/{{ item._id }}" class="item-card-compact__link">
|
|
4
|
+
<a href="{{ readerBaseUrl }}/item/{{ item._id }}" class="ms-item-card-compact__link">
|
|
5
5
|
{% if item.photo and item.photo.length > 0 %}
|
|
6
6
|
<img src="{{ item.photo[0] }}"
|
|
7
7
|
alt=""
|
|
8
|
-
class="item-card-compact__photo"
|
|
9
|
-
loading="lazy"
|
|
10
|
-
onerror="this.style.display='none'">
|
|
8
|
+
class="ms-item-card-compact__photo"
|
|
9
|
+
loading="lazy">
|
|
11
10
|
{% endif %}
|
|
12
|
-
<div class="item-card-compact__body">
|
|
11
|
+
<div class="ms-item-card-compact__body">
|
|
13
12
|
{% if item.name %}
|
|
14
|
-
<h4 class="item-card-compact__title">{{ item.name }}</h4>
|
|
13
|
+
<h4 class="ms-item-card-compact__title">{{ item.name }}</h4>
|
|
15
14
|
{% elif item.content %}
|
|
16
|
-
<p class="item-card-compact__text">
|
|
15
|
+
<p class="ms-item-card-compact__text">
|
|
17
16
|
{% if item.content.text %}{{ item.content.text | truncate(80) }}{% elif item.content.html %}{{ item.content.html | safe | striptags | truncate(80) }}{% endif %}
|
|
18
17
|
</p>
|
|
19
18
|
{% endif %}
|
|
20
|
-
<div class="item-card-compact__meta">
|
|
19
|
+
<div class="ms-item-card-compact__meta">
|
|
21
20
|
{% if item._source %}
|
|
22
|
-
<span class="item-card-compact__source">{{ item._source.name or item._source.url }}</span>
|
|
21
|
+
<span class="ms-item-card-compact__source">{{ item._source.name or item._source.url }}</span>
|
|
23
22
|
{% elif item.author %}
|
|
24
|
-
<span class="item-card-compact__source">{{ item.author.name }}</span>
|
|
23
|
+
<span class="ms-item-card-compact__source">{{ item.author.name }}</span>
|
|
25
24
|
{% endif %}
|
|
26
25
|
{% if item.published %}
|
|
27
|
-
<time datetime="{{ item.published }}" class="item-card-compact__date">
|
|
26
|
+
<time datetime="{{ item.published }}" class="ms-item-card-compact__date">
|
|
28
27
|
{{ item.published | date("PP") }}
|
|
29
28
|
</time>
|
|
30
29
|
{% endif %}
|
|
31
30
|
</div>
|
|
32
31
|
</div>
|
|
33
32
|
{% if not item._is_read %}
|
|
34
|
-
<span class="item-card-compact__unread" aria-label="Unread"></span>
|
|
33
|
+
<span class="ms-item-card-compact__unread" aria-label="Unread"></span>
|
|
35
34
|
{% endif %}
|
|
36
35
|
</a>
|
|
37
36
|
</article>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Item card for timeline display
|
|
3
3
|
Inspired by Aperture/Monocle reader
|
|
4
4
|
#}
|
|
5
|
-
<article class="item-card{% if item._is_read %} item-card--read{% endif %}"
|
|
5
|
+
<article class="ms-item-card{% if item._is_read %} ms-item-card--read{% endif %}"
|
|
6
6
|
data-item-id="{{ item._id }}"
|
|
7
7
|
data-feed-id="{{ item._feedId or '' }}"
|
|
8
8
|
data-is-read="{{ item._is_read | default(false) }}">
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
{% if item["like-of"] and item["like-of"].length > 0 %}
|
|
15
15
|
{% set contextUrl = item['like-of'][0].url or item['like-of'][0].value or item['like-of'][0] %}
|
|
16
|
-
<div class="item-card__context">
|
|
16
|
+
<div class="ms-item-card__context">
|
|
17
17
|
{{ icon("like") }}
|
|
18
18
|
<span>Liked</span>
|
|
19
19
|
<a href="{{ contextUrl }}" target="_blank" rel="noopener">
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
</div>
|
|
23
23
|
{% elif item["repost-of"] and item["repost-of"].length > 0 %}
|
|
24
24
|
{% set contextUrl = item['repost-of'][0].url or item['repost-of'][0].value or item['repost-of'][0] %}
|
|
25
|
-
<div class="item-card__context">
|
|
25
|
+
<div class="ms-item-card__context">
|
|
26
26
|
{{ icon("repost") }}
|
|
27
27
|
<span>Reposted</span>
|
|
28
28
|
<a href="{{ contextUrl }}" target="_blank" rel="noopener">
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
</div>
|
|
32
32
|
{% elif item["in-reply-to"] and item["in-reply-to"].length > 0 %}
|
|
33
33
|
{% set contextUrl = item['in-reply-to'][0].url or item['in-reply-to'][0].value or item['in-reply-to'][0] %}
|
|
34
|
-
<div class="item-card__context">
|
|
34
|
+
<div class="ms-item-card__context">
|
|
35
35
|
{{ icon("reply") }}
|
|
36
36
|
<span>Reply to</span>
|
|
37
37
|
<a href="{{ contextUrl }}" target="_blank" rel="noopener">
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
</div>
|
|
41
41
|
{% elif item["bookmark-of"] and item["bookmark-of"].length > 0 %}
|
|
42
42
|
{% set contextUrl = item['bookmark-of'][0].url or item['bookmark-of'][0].value or item['bookmark-of'][0] %}
|
|
43
|
-
<div class="item-card__context">
|
|
43
|
+
<div class="ms-item-card__context">
|
|
44
44
|
{{ icon("bookmark") }}
|
|
45
45
|
<span>Bookmarked</span>
|
|
46
46
|
<a href="{{ contextUrl }}" target="_blank" rel="noopener">
|
|
@@ -49,43 +49,24 @@
|
|
|
49
49
|
</div>
|
|
50
50
|
{% endif %}
|
|
51
51
|
|
|
52
|
-
<a href="{{ baseUrl }}/item/{{ item._id }}" class="item-card__link">
|
|
52
|
+
<a href="{{ baseUrl }}/item/{{ item._id }}" class="ms-item-card__link">
|
|
53
53
|
{# Author #}
|
|
54
54
|
{% if item.author %}
|
|
55
|
-
<div class="item-card__author">
|
|
55
|
+
<div class="ms-item-card__author">
|
|
56
56
|
{% if item.author.photo %}
|
|
57
57
|
<img src="{{ item.author.photo }}"
|
|
58
58
|
alt=""
|
|
59
|
-
class="item-card__author-photo"
|
|
59
|
+
class="ms-item-card__author-photo"
|
|
60
60
|
width="40"
|
|
61
61
|
height="40"
|
|
62
|
-
loading="lazy"
|
|
63
|
-
onerror="this.style.display='none'">
|
|
62
|
+
loading="lazy">
|
|
64
63
|
{% endif %}
|
|
65
|
-
<div class="item-card__author-info">
|
|
66
|
-
<span class="item-card__author-name">{{ item.author.name or "Unknown" }}</span>
|
|
64
|
+
<div class="ms-item-card__author-info">
|
|
65
|
+
<span class="ms-item-card__author-name">{{ item.author.name or "Unknown" }}</span>
|
|
67
66
|
{% if item._source %}
|
|
68
|
-
<span class="item-card__source">
|
|
69
|
-
{# Protocol source indicator #}
|
|
70
|
-
{% set sourceUrl = item._source.url or item.author.url or "" %}
|
|
71
|
-
{% set sourceType = item._source.source_type or item._source.type %}
|
|
72
|
-
{% if sourceType == "activitypub" or sourceType == "mastodon" or ("mastodon." in sourceUrl) or ("mstdn." in sourceUrl) or ("fosstodon." in sourceUrl) or ("pleroma." in sourceUrl) or ("misskey." in sourceUrl) %}
|
|
73
|
-
<svg class="item-card__source-icon" viewBox="0 0 24 24" fill="#6364ff" aria-label="Fediverse" style="width:12px;height:12px;vertical-align:middle;margin-right:3px;display:inline-block">
|
|
74
|
-
<path d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.668 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z"/>
|
|
75
|
-
</svg>
|
|
76
|
-
{% elif sourceType == "bluesky" or ("bsky.app" in sourceUrl) or ("bluesky" in sourceUrl) %}
|
|
77
|
-
<svg class="item-card__source-icon" viewBox="0 0 568 501" fill="#0085ff" aria-label="ATmosphere" style="width:12px;height:12px;vertical-align:middle;margin-right:3px;display:inline-block">
|
|
78
|
-
<path d="M123.121 33.664C188.241 82.553 258.281 181.68 284 234.873c25.719-53.192 95.759-152.32 160.879-201.21C491.866-1.611 568-28.906 568 57.947c0 17.346-9.945 145.713-15.778 166.555-20.275 72.453-94.155 90.933-159.875 79.748C507.222 323.8 536.444 388.56 473.333 453.32c-119.86 122.992-172.272-30.859-185.702-70.281-2.462-7.227-3.614-10.608-3.631-7.733-.017-2.875-1.169.506-3.631 7.733-13.43 39.422-65.842 193.273-185.702 70.281-63.111-64.76-33.89-129.52 80.986-149.071-65.72 11.185-139.6-7.295-159.875-79.748C9.945 203.659 0 75.291 0 57.946 0-28.906 76.135-1.612 123.121 33.664Z"/>
|
|
79
|
-
</svg>
|
|
80
|
-
{% else %}
|
|
81
|
-
<svg class="item-card__source-icon" viewBox="0 0 24 24" fill="none" stroke="#888" stroke-width="2" aria-label="Web" style="width:12px;height:12px;vertical-align:middle;margin-right:3px;display:inline-block">
|
|
82
|
-
<circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>
|
|
83
|
-
</svg>
|
|
84
|
-
{% endif %}
|
|
85
|
-
{{ item._source.name or item._source.url }}
|
|
86
|
-
</span>
|
|
67
|
+
<span class="ms-item-card__source">{{ item._source.name or item._source.url }}</span>
|
|
87
68
|
{% elif item.author.url %}
|
|
88
|
-
<span class="item-card__source">{{ item.author.url | replace("https://", "") | replace("http://", "") }}</span>
|
|
69
|
+
<span class="ms-item-card__source">{{ item.author.url | replace("https://", "") | replace("http://", "") }}</span>
|
|
89
70
|
{% endif %}
|
|
90
71
|
</div>
|
|
91
72
|
</div>
|
|
@@ -93,12 +74,12 @@
|
|
|
93
74
|
|
|
94
75
|
{# Title (for articles) #}
|
|
95
76
|
{% if item.name %}
|
|
96
|
-
<h3 class="item-card__title">{{ item.name }}</h3>
|
|
77
|
+
<h3 class="ms-item-card__title">{{ item.name }}</h3>
|
|
97
78
|
{% endif %}
|
|
98
79
|
|
|
99
80
|
{# Content with overflow handling #}
|
|
100
81
|
{% if item.summary or item.content %}
|
|
101
|
-
<div class="item-card__content{% if (item.content.text or item.summary or '') | length > 300 %} item-card__content--truncated{% endif %}">
|
|
82
|
+
<div class="ms-item-card__content{% if (item.content.text or item.summary or '') | length > 300 %} ms-item-card__content--truncated{% endif %}">
|
|
102
83
|
{% if item.content.html %}
|
|
103
84
|
{{ item.content.html | safe | striptags | truncate(400) }}
|
|
104
85
|
{% elif item.content.text %}
|
|
@@ -111,10 +92,10 @@
|
|
|
111
92
|
|
|
112
93
|
{# Categories/Tags #}
|
|
113
94
|
{% if item.category and item.category.length > 0 %}
|
|
114
|
-
<div class="item-card__categories">
|
|
95
|
+
<div class="ms-item-card__categories">
|
|
115
96
|
{% for cat in item.category %}
|
|
116
97
|
{% if loop.index0 < 5 %}
|
|
117
|
-
<span class="item-card__category">#{{ cat | replace("#", "") }}</span>
|
|
98
|
+
<span class="ms-item-card__category">#{{ cat | replace("#", "") }}</span>
|
|
118
99
|
{% endif %}
|
|
119
100
|
{% endfor %}
|
|
120
101
|
</div>
|
|
@@ -123,14 +104,13 @@
|
|
|
123
104
|
{# Photo grid (Aperture multi-photo pattern) #}
|
|
124
105
|
{% if item.photo and item.photo.length > 0 %}
|
|
125
106
|
{% set photoCount = item.photo.length if item.photo.length <= 4 else 4 %}
|
|
126
|
-
<div class="item-card__photos item-card__photos--{{ photoCount }}">
|
|
107
|
+
<div class="ms-item-card__photos ms-item-card__photos--{{ photoCount }}">
|
|
127
108
|
{% for photo in item.photo %}
|
|
128
109
|
{% if loop.index0 < 4 %}
|
|
129
110
|
<img src="{{ photo }}"
|
|
130
111
|
alt=""
|
|
131
|
-
class="item-card__photo"
|
|
132
|
-
loading="lazy"
|
|
133
|
-
onerror="this.parentElement.removeChild(this)">
|
|
112
|
+
class="ms-item-card__photo"
|
|
113
|
+
loading="lazy">
|
|
134
114
|
{% endif %}
|
|
135
115
|
{% endfor %}
|
|
136
116
|
</div>
|
|
@@ -138,9 +118,9 @@
|
|
|
138
118
|
|
|
139
119
|
{# Video preview #}
|
|
140
120
|
{% if item.video and item.video.length > 0 %}
|
|
141
|
-
<div class="item-card__media">
|
|
121
|
+
<div class="ms-item-card__media">
|
|
142
122
|
<video src="{{ item.video[0] }}"
|
|
143
|
-
class="item-card__video"
|
|
123
|
+
class="ms-item-card__video"
|
|
144
124
|
controls
|
|
145
125
|
preload="metadata"
|
|
146
126
|
{% if item.photo and item.photo.length > 0 %}poster="{{ item.photo[0] }}"{% endif %}>
|
|
@@ -150,74 +130,74 @@
|
|
|
150
130
|
|
|
151
131
|
{# Audio preview #}
|
|
152
132
|
{% if item.audio and item.audio.length > 0 %}
|
|
153
|
-
<div class="item-card__media">
|
|
154
|
-
<audio src="{{ item.audio[0] }}" class="item-card__audio" controls preload="metadata"></audio>
|
|
133
|
+
<div class="ms-item-card__media">
|
|
134
|
+
<audio src="{{ item.audio[0] }}" class="ms-item-card__audio" controls preload="metadata"></audio>
|
|
155
135
|
</div>
|
|
156
136
|
{% endif %}
|
|
157
137
|
|
|
158
138
|
{# Footer with date and actions #}
|
|
159
|
-
<footer class="item-card__footer">
|
|
139
|
+
<footer class="ms-item-card__footer">
|
|
160
140
|
{% if item.published %}
|
|
161
|
-
<time datetime="{{ item.published }}" class="item-card__date">
|
|
141
|
+
<time datetime="{{ item.published }}" class="ms-item-card__date">
|
|
162
142
|
{{ item.published | date("PP", { locale: locale, timeZone: application.timeZone }) }}
|
|
163
143
|
</time>
|
|
164
144
|
{% endif %}
|
|
165
145
|
{% if not item._is_read %}
|
|
166
|
-
<span class="item-card__unread" aria-label="Unread">●</span>
|
|
146
|
+
<span class="ms-item-card__unread" aria-label="Unread">●</span>
|
|
167
147
|
{% endif %}
|
|
168
148
|
</footer>
|
|
169
149
|
</a>
|
|
170
150
|
|
|
171
151
|
{# Inline actions (Aperture pattern) #}
|
|
172
|
-
<div class="item-actions">
|
|
152
|
+
<div class="ms-item-actions">
|
|
173
153
|
{% if item._source and item._source.type === "activitypub" and item.author and item.author.url %}
|
|
174
|
-
<a href="{{ baseUrl }}/actor?url={{ item.author.url | urlencode }}" class="item-actions__button" title="View actor profile">
|
|
154
|
+
<a href="{{ baseUrl }}/actor?url={{ item.author.url | urlencode }}" class="ms-item-actions__button" title="View actor profile">
|
|
175
155
|
{{ icon("mention") }}
|
|
176
|
-
<span class="visually-hidden">Actor profile</span>
|
|
156
|
+
<span class="-!-visually-hidden">Actor profile</span>
|
|
177
157
|
</a>
|
|
178
158
|
{% endif %}
|
|
179
159
|
{% if item.url %}
|
|
180
|
-
<a href="{{ item.url }}" class="item-actions__button" target="_blank" rel="noopener" title="View original">
|
|
160
|
+
<a href="{{ item.url }}" class="ms-item-actions__button" target="_blank" rel="noopener" title="View original">
|
|
181
161
|
{{ icon("external") }}
|
|
182
|
-
<span class="visually-hidden">Original</span>
|
|
162
|
+
<span class="-!-visually-hidden">Original</span>
|
|
183
163
|
</a>
|
|
184
164
|
{% endif %}
|
|
185
|
-
<a href="{{ baseUrl }}/compose?reply={{ item.url | urlencode }}" class="item-actions__button" title="Reply">
|
|
165
|
+
<a href="{{ baseUrl }}/compose?reply={{ item.url | urlencode }}" class="ms-item-actions__button" title="Reply">
|
|
186
166
|
{{ icon("reply") }}
|
|
187
|
-
<span class="visually-hidden">Reply</span>
|
|
167
|
+
<span class="-!-visually-hidden">Reply</span>
|
|
188
168
|
</a>
|
|
189
|
-
<a href="{{ baseUrl }}/compose?like={{ item.url | urlencode }}" class="item-actions__button" title="Like">
|
|
169
|
+
<a href="{{ baseUrl }}/compose?like={{ item.url | urlencode }}" class="ms-item-actions__button" title="Like">
|
|
190
170
|
{{ icon("like") }}
|
|
191
|
-
<span class="visually-hidden">Like</span>
|
|
171
|
+
<span class="-!-visually-hidden">Like</span>
|
|
192
172
|
</a>
|
|
193
|
-
<a href="{{ baseUrl }}/compose?repost={{ item.url | urlencode }}" class="item-actions__button" title="Repost">
|
|
173
|
+
<a href="{{ baseUrl }}/compose?repost={{ item.url | urlencode }}" class="ms-item-actions__button" title="Repost">
|
|
194
174
|
{{ icon("repost") }}
|
|
195
|
-
<span class="visually-hidden">Repost</span>
|
|
175
|
+
<span class="-!-visually-hidden">Repost</span>
|
|
196
176
|
</a>
|
|
197
|
-
<a href="{{ baseUrl }}/compose?bookmark={{ item.url | urlencode }}" class="item-actions__button" title="Bookmark">
|
|
177
|
+
<a href="{{ baseUrl }}/compose?bookmark={{ item.url | urlencode }}" class="ms-item-actions__button" title="Bookmark">
|
|
198
178
|
{{ icon("bookmark") }}
|
|
199
|
-
<span class="visually-hidden">Bookmark</span>
|
|
179
|
+
<span class="-!-visually-hidden">Bookmark</span>
|
|
200
180
|
</a>
|
|
201
181
|
{% if not item._is_read %}
|
|
202
182
|
{% if item._feedId %}
|
|
203
|
-
<span class="item-actions__mark-read-group">
|
|
183
|
+
<span class="ms-item-actions__mark-read-group">
|
|
204
184
|
<button type="button"
|
|
205
|
-
class="item-actions__button item-actions__mark-read"
|
|
185
|
+
class="ms-item-actions__button ms-item-actions__mark-read"
|
|
206
186
|
data-action="mark-read"
|
|
207
187
|
data-item-id="{{ item._id }}"
|
|
208
188
|
{% if item._channelUid %}data-channel-uid="{{ item._channelUid }}"{% endif %}
|
|
209
189
|
{% if item._channelId %}data-channel-id="{{ item._channelId }}"{% endif %}
|
|
210
190
|
title="Mark as read">
|
|
211
191
|
{{ icon("checkboxChecked") }}
|
|
212
|
-
<span class="visually-hidden">Mark read</span>
|
|
192
|
+
<span class="-!-visually-hidden">Mark read</span>
|
|
213
193
|
</button>
|
|
214
194
|
<button type="button"
|
|
215
|
-
class="item-actions__button item-actions__mark-read-caret"
|
|
195
|
+
class="ms-item-actions__button ms-item-actions__mark-read-caret"
|
|
216
196
|
aria-label="More mark-read options"
|
|
217
197
|
title="More options">▾</button>
|
|
218
|
-
<div class="item-actions__mark-read-popover" hidden>
|
|
198
|
+
<div class="ms-item-actions__mark-read-popover" hidden>
|
|
219
199
|
<button type="button"
|
|
220
|
-
class="item-actions__mark-source-read"
|
|
200
|
+
class="ms-item-actions__mark-source-read"
|
|
221
201
|
data-feed-id="{{ item._feedId }}"
|
|
222
202
|
{% if item._channelUid %}data-channel-uid="{{ item._channelUid }}"{% endif %}
|
|
223
203
|
{% if item._channelId %}data-channel-id="{{ item._channelId }}"{% endif %}>
|
|
@@ -227,26 +207,26 @@
|
|
|
227
207
|
</span>
|
|
228
208
|
{% else %}
|
|
229
209
|
<button type="button"
|
|
230
|
-
class="item-actions__button item-actions__mark-read"
|
|
210
|
+
class="ms-item-actions__button ms-item-actions__mark-read"
|
|
231
211
|
data-action="mark-read"
|
|
232
212
|
data-item-id="{{ item._id }}"
|
|
233
213
|
{% if item._channelUid %}data-channel-uid="{{ item._channelUid }}"{% endif %}
|
|
234
214
|
{% if item._channelId %}data-channel-id="{{ item._channelId }}"{% endif %}
|
|
235
215
|
title="Mark as read">
|
|
236
216
|
{{ icon("checkboxChecked") }}
|
|
237
|
-
<span class="visually-hidden">Mark read</span>
|
|
217
|
+
<span class="-!-visually-hidden">Mark read</span>
|
|
238
218
|
</button>
|
|
239
219
|
{% endif %}
|
|
240
220
|
{% endif %}
|
|
241
221
|
{% if application.readlaterEndpoint %}
|
|
242
222
|
<button type="button"
|
|
243
|
-
class="item-actions__button item-actions__save-later"
|
|
223
|
+
class="ms-item-actions__button ms-item-actions__save-later"
|
|
244
224
|
data-action="save-later"
|
|
245
225
|
data-url="{{ item.url }}"
|
|
246
226
|
data-title="{{ item.name or '' }}"
|
|
247
227
|
title="Save for later">
|
|
248
228
|
{{ icon("bookmark") }}
|
|
249
|
-
<span class="visually-hidden">Save for later</span>
|
|
229
|
+
<span class="-!-visually-hidden">Save for later</span>
|
|
250
230
|
</button>
|
|
251
231
|
{% endif %}
|
|
252
232
|
</div>
|