nodebb-theme-persona 14.2.40 → 14.2.42

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-theme-persona",
3
- "version": "14.2.40",
3
+ "version": "14.2.42",
4
4
  "nbbpm": {
5
5
  "compatibility": "^4.13.0"
6
6
  },
package/public/persona.js CHANGED
@@ -186,7 +186,7 @@ $(document).ready(function () {
186
186
  avatar.parents('a').after(card.hide());
187
187
 
188
188
  if (String(app.user.uid) === String(user.uid) || !app.user.uid) {
189
- card.find('.btn-morph').hide();
189
+ card.find('.btn-morph').addClass('invisible');
190
190
  } else {
191
191
  const uid = isFinite(user.uid) ? user.uid : encodeURIComponent(user.userslug);
192
192
  setupFavouriteMorph(card, uid, user.username);
@@ -1,65 +1,13 @@
1
1
  .persona-usercard {
2
2
  position: absolute;
3
- background: #333;
4
3
  top: -50%;
5
4
  left: 0px;
6
5
  box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.25), 0px 2px 10px 0px rgba(0, 0, 0, 0.25);
7
6
  height: 150px;
8
7
  width: 450px;
9
- z-index: 1;
10
- display: block;
8
+ z-index: $zindex-dropdown;
11
9
 
12
- a, a:hover, a:visited, a:active {
13
- text-decoration: none;
14
- color: white;
15
- }
16
-
17
- .usercard-picture {
18
- width: 150px;
19
- height: 150px;
20
- float: left;
21
- background-size: cover;
22
- background-repeat: no-repeat;
23
- font-size: 75px;
24
- line-height: 140px;
25
- text-align: center;
26
- }
27
-
28
- .usercard-body {
29
- padding: 5px 15px;
30
- float: left;
31
-
32
- height: 150px;
33
- width: 300px;
34
- color: white;
35
- }
36
-
37
- .usercard-name {
38
- font-size: 28px;
39
- }
40
-
41
- .usercard-username {
42
- text-transform: uppercase;
43
- font-size: 13px;
44
- }
45
-
46
- .usercard-info {
47
- text-align: center;
48
- font-size: 30px;
49
- font-weight: 300;
50
-
51
- small {
52
- text-transform: uppercase;
53
- font-size: 10px;
54
- display: block;
55
- margin-top: 15px;
56
- font-weight: 400;
57
- }
58
- }
59
-
60
- .persona-fab.btn-morph {
61
- top: 75px;
62
- right: 15px;
63
- position: absolute;
10
+ .avatar {
11
+ margin: 0!important;
64
12
  }
65
13
  }
@@ -3,15 +3,6 @@
3
3
  <div class="row">
4
4
  <div class="col-md-3 col-sm-4">
5
5
  <div class="account-picture-block text-center">
6
- <div class="row mb-3">
7
- <div class="col-12 hidden-xs">
8
- <!-- IF picture -->
9
- <img id="user-current-picture" class="avatar avatar-rounded" style="--avatar-size: 128px;" src="{picture}" />
10
- <!-- ELSE -->
11
- <div class="avatar avatar-rounded" style="background-color: {icon:bgColor}; --avatar-size: 128px;">{icon:text}</div>
12
- <!-- ENDIF picture -->
13
- </div>
14
- </div>
15
6
  <ul class="list-group mb-3">
16
7
  {{{ if allowProfilePicture }}}
17
8
  <li class="list-group-item"><a component="profile/change/picture" href="#" class="text-decoration-none text-reset">[[user:change-picture]]</a></li>
@@ -6,24 +6,7 @@
6
6
  <p class="lead">[[user:sessions.description]]</p>
7
7
  <hr />
8
8
  <ul class="list-group" component="user/sessions">
9
- {{{each sessions}}}
10
- <li class="list-group-item" data-uuid="{../uuid}">
11
- <div class="float-end">
12
- <!-- IF isSelfOrAdminOrGlobalModerator -->
13
- <!-- IF !../current -->
14
- <button class="btn btn-sm btn-outline-secondary" type="button" data-action="revokeSession">Revoke Session</button>
15
- <!-- ENDIF !../current -->
16
- <!-- ENDIF isSelfOrAdminOrGlobalModerator -->
17
- {function.userAgentIcons}
18
- <i class="fa fa-circle text-<!-- IF ../current -->success<!-- ELSE -->muted<!-- ENDIF ../current -->"></i>
19
- </div>
20
- {../browser} {../version} on {../platform}<br />
21
- <small class="timeago text-muted" title="{../datetimeISO}"></small>
22
- <ul>
23
- <li><strong>[[global:ip-address]]</strong>: {../ip}</li>
24
- </ul>
25
- </li>
26
- {{{end}}}
9
+ <!-- IMPORT partials/account/session-list.tpl -->
27
10
  </ul>
28
11
  </div>
29
12
  </div>
@@ -1,6 +1,6 @@
1
1
  <div component="groups/container" class="groups details">
2
2
 
3
- <div component="groups/cover" style="background-image: url({group.cover:url}??{config.cache-buster}); background-position: {group.cover:position};">
3
+ <div component="groups/cover" style="background-image: url({escape(group.cover:url)}?{config.cache-buster}); background-position: {group.cover:position};">
4
4
  {{{ if group.isOwner }}}
5
5
  <div class="controls">
6
6
  <span class="upload"><i class="fa fa-fw fa-4x fa-upload"></i></span>
@@ -31,7 +31,7 @@
31
31
  </div>
32
32
  <div class="d-flex gap-2 align-items-start">
33
33
  {{{ if loggedIn }}}
34
- {function.membershipBtn, group}
34
+ {membershipBtn(group)}
35
35
  {{{ end }}}
36
36
  {{{ if isAdmin }}}
37
37
  <a href="{config.relative_path}/admin/manage/groups/{group.slug}" target="_blank" class="btn btn-light text-nowrap"><i class="fa fa-gear"></i> [[user:edit]]</a>
@@ -1,10 +1,10 @@
1
1
  <!DOCTYPE html>
2
- <html lang="{function.localeToHTML, userLang, defaultLang}" {{{if languageDirection}}}data-dir="{languageDirection}" style="direction: {languageDirection};"{{{end}}}>
2
+ <html lang="{localeToHTML(userLang, defaultLang)}" {{{if languageDirection}}}data-dir="{languageDirection}" style="direction: {languageDirection};"{{{end}}}>
3
3
  <head>
4
4
  <title>{browserTitle}</title>
5
- {{{each metaTags}}}{function.buildMetaTag}{{{end}}}
5
+ {{{each metaTags}}}{buildMetaTag(@value)}{{{end}}}
6
6
  <link rel="stylesheet" type="text/css" href="{relative_path}/assets/client{{{if bootswatchSkin}}}-{bootswatchSkin}{{{end}}}{{{ if (languageDirection=="rtl") }}}-rtl{{{ end }}}.css?{config.cache-buster}" />
7
- {{{each linkTags}}}{function.buildLinkTag}{{{end}}}
7
+ {{{each linkTags}}}{buildLinkTag(@value)}{{{end}}}
8
8
 
9
9
  <script>
10
10
  var config = JSON.parse('{{configJSON}}');
@@ -1,31 +1,32 @@
1
- <div class="persona-usercard">
1
+ <div class="persona-usercard d-flex text-bg-dark">
2
2
  <a href="{config.relative_path}/user/{userslug}">
3
- <!-- IF picture -->
4
- <div class="usercard-picture" style="background-image:url({picture})"></div>
5
- <!-- ELSE -->
6
- <div class="usercard-picture" style="background-color: {icon:bgColor};">{icon:text}</div>
7
- <!-- ENDIF picture -->
3
+ {buildAvatar(@value, "150px", false, "shadow-none")}
8
4
  </a>
9
- <div class="usercard-body">
10
- <a href="{config.relative_path}/user/{userslug}">
11
- <span class="usercard-name"><!-- IF fullname -->{fullname}<!-- ELSE -->{username}<!-- ENDIF fullname --></span><br />
12
- <span class="usercard-username"><!-- IF !banned -->@{username}<!-- ELSE -->[[user:banned]]<!-- ENDIF !banned --></span>
13
- <!-- IF !banned -->
14
- <i component="user/status" class="fa fa-circle status {status}" title="[[global:{status}]]"></i>
15
- <!-- ENDIF !banned -->
5
+ <div class="usercard-body w-100 d-flex flex-column justify-content-between gap-2 py-2 px-3 overflow-hidden position-relative">
6
+
7
+ <a href="{config.relative_path}/user/{userslug}" class="text-reset text-truncate d-block">
8
+ <span class="usercard-name fs-5">{{{ if fullname }}}{fullname}{{{ else }}}{username}{{{ end }}}</span>
16
9
  </a>
17
10
 
18
- <div class="row usercard-info">
19
- <div class="col-4">
11
+ <div class="d-flex gap-2 align-items-center">
12
+ <a href="{config.relative_path}/user/{userslug}" class="text-reset text-truncate d-block">
13
+ <span class="usercard-username text-uppercase text-sm text-truncate">{{{ if !banned }}}@{username}{{{ else }}}[[user:banned]]{{{ end }}}</span>
14
+ </a>
15
+ {{{ if !banned }}}
16
+ <span component="user/status" class="border border-white border-2 m-0 rounded-circle status {status}" title="[[global:{status}]]" style="transform: none;"><span class="visually-hidden">[[global:{posts.user.status}]]</span></span>
17
+ {{{ end }}}
18
+ </div>
19
+
20
+ <div class="d-flex justify-content-between usercard-info">
21
+ <div class="d-flex flex-column text-center">
20
22
  <small>[[global:posts]]</small>
21
- <span>{humanReadableNumber(postcount)}</span>
23
+ <span class="fs-5">{humanReadableNumber(postcount)}</span>
22
24
  </div>
23
- <div class="col-4">
25
+ <div class="d-flex flex-column text-center">
24
26
  <small>[[global:reputation]]</small>
25
- <span>{humanReadableNumber(reputation)}</span>
27
+ <span class="fs-5">{humanReadableNumber(reputation)}</span>
26
28
  </div>
27
-
28
- <button class="btn-morph persona-fab <!-- IF banned --> hide<!-- ENDIF banned -->">
29
+ <button class="btn-morph persona-fab fs-3 {{{ if banned }}} invisible{{{ end }}}">
29
30
  <span>
30
31
  <span class="s1"></span>
31
32
  <span class="s2"></span>
@@ -34,4 +35,5 @@
34
35
  </button>
35
36
  </div>
36
37
  </div>
38
+
37
39
  </div>
@@ -7,29 +7,24 @@
7
7
  {{{end}}}
8
8
  </div>
9
9
 
10
- <div class="cover" component="account/cover" style="background-image: url({cover:url}); background-position: {cover:position};">
10
+ <div class="cover" component="account/cover" style="background-image: url({escape(cover:url)}); background-position: {cover:position};">
11
11
  <div class="avatar-wrapper" data-uid="{uid}">
12
- <!-- IF picture -->
13
- <img src="{picture}" class="avatar avatar-rounded" style="--avatar-size: 128px;" />
14
- <!-- ELSE -->
15
- <div class="avatar avatar-rounded" style="background-color: {icon:bgColor}; --avatar-size: 128px;" title="{username}">{icon:text}</div>
16
- <!-- ENDIF picture -->
12
+ {buildAvatar(@value, "128px", true)}
17
13
  <span component="user/status" class="position-absolute border border-white border-2 rounded-circle status {status}"><span class="visually-hidden">[[global:{status}]]</span></span>
18
14
 
19
- <!-- IF !isSelf -->
20
- <button class="btn-morph persona-fab <!-- IF isFollowing -->heart<!-- ELSE -->plus<!-- ENDIF isFollowing -->" title="<!-- IF isFollowing -->[[global:unfollow]]<!-- ELSE -->[[global:follow]]<!-- ENDIF isFollowing -->">
15
+ {{{ if !isSelf }}}
16
+ <button class="btn-morph persona-fab {{{ if isFollowing }}}heart{{{ else }}}plus{{{ end }}}" title="{{{ if isFollowing }}}[[global:unfollow]]{{{ else }}}[[global:follow]]{{{ end }}}">
21
17
  <span>
22
18
  <span class="s1"></span>
23
19
  <span class="s2"></span>
24
20
  <span class="s3"></span>
25
21
  </span>
26
22
  </button>
27
- <!-- ENDIF !isSelf -->
23
+ {{{ end }}}
28
24
  </div>
29
25
 
30
26
  <div class="container">
31
- <!-- IF allowCoverPicture -->
32
- <!-- IF canEdit -->
27
+ {{{ if (allowCoverPicture && canEdit) }}}
33
28
  <div class="controls">
34
29
  <a href="#" class="upload"><i class="fa fa-fw fa-4x fa-upload"></i></a>
35
30
  <a href="#" class="resize"><i class="fa fa-fw fa-4x fa-arrows"></i></a>
@@ -37,8 +32,7 @@
37
32
  </div>
38
33
  <a href="#" class="save">[[groups:cover-save]] <i class="fa fa-fw fa-floppy-o"></i></a>
39
34
  <div class="indicator">[[groups:cover-saving]] <i class="fa fa-fw fa-refresh fa-spin"></i></div>
40
- <!-- ENDIF canEdit -->
41
- <!-- ENDIF allowCoverPicture -->
35
+ {{{ end }}}
42
36
 
43
37
  <!-- IMPORT partials/account/menu.tpl -->
44
38
  </div>
@@ -6,7 +6,7 @@
6
6
  <button class="btn btn-sm btn-outline-secondary" type="button" data-action="revokeSession">[[user:revoke-session]]</button>
7
7
  {{{ end }}}
8
8
  {{{ end }}}
9
- {function.userAgentIcons}
9
+ {userAgentIcons(@value)}
10
10
  <i class="fa fa-circle text-{{{ if ./current }}}success{{{ else }}}muted{{{ end }}}"></i>
11
11
  </div>
12
12
  [[user:browser-version-on-platform, {./browser}, {./version}, {./platform}]]<br />
@@ -46,7 +46,7 @@
46
46
  <div id="nav-dropdown" class="collapse navbar-collapse d-none d-lg-block">
47
47
  <ul id="main-nav" class="navbar-nav me-auto mb-2 mb-lg-0">
48
48
  {{{each navigation}}}
49
- <!-- IF function.displayMenuItem, @index -->
49
+ {{{ if displayMenuItem(@root, @index) }}}
50
50
  <li class="nav-item {navigation.class}{{{ if navigation.dropdown }}} dropdown{{{ end }}}" title="{navigation.title}">
51
51
  <a class="nav-link navigation-link {{{ if navigation.dropdown }}}dropdown-toggle{{{ end }}}"
52
52
  {{{ if navigation.dropdown }}} href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" {{{ else }}} href="{navigation.route}"{{{ end }}} {{{ if navigation.id }}}id="{navigation.id}"{{{ end }}}{{{ if navigation.targetBlank }}} target="_blank"{{{ end }}}>
@@ -66,8 +66,8 @@
66
66
  </ul>
67
67
  {{{ end }}}
68
68
  </li>
69
- <!-- ENDIF function.displayMenuItem -->
70
- {{{end}}}
69
+ {{{ end }}}
70
+ {{{ end }}}
71
71
  </ul>
72
72
  <ul class="navbar-nav mb-2 mb-lg-0 hidden-xs">
73
73
  <li class="nav-item">
@@ -1,6 +1,6 @@
1
1
  <div id="results" class="search-results col-md-12" data-search-query="{search_query}">
2
2
  {{{ if matchCount }}}
3
- <div class="alert alert-info">[[search:results-matching, {matchCount}, {search_query}, {time}]] </div>
3
+ <div class="alert alert-info">[[search:results-matching, {matchCount}, {txEscape(search_query)}, {time}]] </div>
4
4
  {{{ else }}}
5
5
  {{{ if search_query }}}
6
6
  <div class="alert alert-warning">[[search:no-matches]]</div>
@@ -3,8 +3,8 @@
3
3
  <button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
4
4
  <span class="caret"></span>
5
5
  </button>
6
- <ul class="dropdown-menu dropdown-menu-end" role="menu">
7
- <li><a class="dropdown-item" href="#" component="topic/reply-as-topic" role="menuitem">[[topic:reply-as-topic]]</a></li>
6
+ <ul class="dropdown-menu dropdown-menu-end p-1" role="menu">
7
+ <li><a class="dropdown-item rounded-1" href="#" component="topic/reply-as-topic" role="menuitem">[[topic:reply-as-topic]]</a></li>
8
8
  </ul>
9
9
  </div>
10
10
 
@@ -1,9 +1,9 @@
1
1
  <ul component="category" class="topics-list list-unstyled" itemscope itemtype="http://www.schema.org/ItemList" data-nextstart="{nextStart}" data-set="{set}">
2
2
 
3
3
  {{{ each topics }}}
4
- <li component="category/topic" class="category-item hover-parent py-2 mb-2 d-flex flex-column flex-lg-row align-items-start {function.generateTopicClass}" <!-- IMPORT partials/data/category.tpl -->>
4
+ <li component="category/topic" class="category-item hover-parent py-2 mb-2 d-flex flex-column flex-lg-row align-items-start {generateTopicClass(@value)}" <!-- IMPORT partials/data/category.tpl -->>
5
5
  <link itemprop="url" content="{config.relative_path}/topic/{./slug}" />
6
- <meta itemprop="name" content="{function.stripTags, ./title}" />
6
+ <meta itemprop="name" content="{stripTags(./title)}" />
7
7
  <meta itemprop="itemListOrder" content="descending" />
8
8
  <meta itemprop="position" content="{increment(./index, "1")}" />
9
9
  <a id="{./index}" data-index="{./index}" component="topic/anchor"></a>
@@ -51,7 +51,7 @@
51
51
  {{{each ./icons}}}<span class="lh-1">{@value}</span>{{{end}}}
52
52
 
53
53
  {{{ if (!template.category || (cid != ./cid)) }}}
54
- {function.buildCategoryLabel, ./category, "a", "border"}
54
+ {buildCategoryLabel(./category, "a", "border")}
55
55
  {{{ end }}}
56
56
 
57
57
  <span data-tid="{./tid}" component="topic/tags" class="lh-1 tag-list d-flex flex-wrap gap-1 {{{ if !./tags.length }}}hidden{{{ end }}}">
@@ -40,7 +40,7 @@
40
40
  </a>
41
41
  {{{each icons}}}<span class="lh-1">{@value}</span>{{{end}}}
42
42
  </span>
43
- {function.buildCategoryLabel, category, "a", "border"}
43
+ {buildCategoryLabel(category, "a", "border")}
44
44
  <div data-tid="{./tid}" component="topic/tags" class="lh-1 tags tag-list d-flex flex-wrap hidden-xs hidden-empty gap-2"><!-- IMPORT partials/topic/tags.tpl --></div>
45
45
  <div class="d-flex gap-2" component="topic/stats"><!-- IMPORT partials/topic/stats.tpl --></div>
46
46
  {{{ if !feeds:disableRSS }}}