nodebb-plugin-composer-default 10.0.20 → 10.0.22

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-plugin-composer-default",
3
- "version": "10.0.20",
3
+ "version": "10.0.22",
4
4
  "description": "Default composer for NodeBB",
5
5
  "main": "library.js",
6
6
  "repository": {
@@ -2,7 +2,7 @@
2
2
 
3
3
  define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
4
4
  const drafts = {};
5
- const draftSaveDelay = 2000;
5
+ const draftSaveDelay = 1000;
6
6
  drafts.init = function (postContainer, postData) {
7
7
  const draftIconEl = postContainer.find('.draft-icon');
8
8
  function doSaveDraft() {
@@ -74,7 +74,7 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
74
74
  function saveDraft(postContainer, draftIconEl, postData) {
75
75
  if (canSave(app.user.uid ? 'localStorage' : 'sessionStorage') && postData && postData.save_id && postContainer.length) {
76
76
  const titleEl = postContainer.find('input.title');
77
- const title = titleEl && titleEl.val();
77
+ const title = titleEl && titleEl.length && titleEl.val();
78
78
  const raw = postContainer.find('textarea').val();
79
79
  const storage = getStorage(app.user.uid);
80
80
 
@@ -100,6 +100,7 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
100
100
  draftData.toPid = postData.toPid;
101
101
  } else if (postData.action === 'posts.edit') {
102
102
  draftData.pid = postData.pid;
103
+ draftData.title = title;
103
104
  }
104
105
  if (!app.user.uid) {
105
106
  draftData.handle = postContainer.find('input.handle').val();
@@ -297,6 +298,7 @@ define('composer/drafts', ['api', 'alerts'], function (api, alerts) {
297
298
  composer.editPost({
298
299
  save_id: draft.save_id,
299
300
  pid: draft.pid,
301
+ title: draft.title ? utils.escapeHTML(draft.title) : undefined,
300
302
  body: utils.escapeHTML(draft.text),
301
303
  });
302
304
  }
@@ -81,7 +81,7 @@ define('composer/formatting', [
81
81
  };
82
82
 
83
83
  formatting.addButton = function (iconClass, onClick, title, name) {
84
- name = name || iconClass.replace('fa fa-', '')
84
+ name = name || iconClass.replace('fa fa-', '');
85
85
  formattingDispatchTable[name] = onClick;
86
86
  buttons.push({
87
87
  name,
@@ -99,7 +99,7 @@ define('composer/formatting', [
99
99
  };
100
100
 
101
101
  formatting.addHandler = function (postContainer) {
102
- postContainer.on('click', '.formatting-bar li', function (event) {
102
+ postContainer.on('click', '.formatting-bar li a', function (event) {
103
103
  var format = $(this).attr('data-format');
104
104
  var textarea = $(this).parents('[component="composer"]').find('textarea')[0];
105
105
 
@@ -43,63 +43,54 @@ define('composer/preview', ['hooks'], function (hooks) {
43
43
  }
44
44
  };
45
45
 
46
- preview.handleToggler = function (postContainer) {
47
- preview.env = utils.findBootstrapEnvironment();
48
- var showBtn = postContainer.find('.write-container .toggle-preview');
49
- var hideBtn = postContainer.find('.preview-container .toggle-preview');
50
- var previewContainer = $('.preview-container');
51
- var writeContainer = $('.write-container');
52
-
53
- function hidePreview() {
54
- togglePreview(false);
55
- if (preview.env !== 'xs' && preview.env !== 'sm') {
56
- localStorage.setItem('composer:previewToggled', true);
57
- }
58
- }
46
+ preview.handleToggler = function ($postContainer) {
47
+ const postContainer = $postContainer.get(0);
59
48
 
60
- function showPreview() {
61
- togglePreview(true);
62
- if (preview.env !== 'xs' && preview.env !== 'sm') {
63
- localStorage.removeItem('composer:previewToggled');
64
- }
49
+ const isMobile = ['xs', 'sm'].includes(utils.findBootstrapEnvironment());
50
+ const toggler = postContainer.querySelector('.formatting-bar [data-action="preview"]');
51
+ let show = localStorage.getItem('composer:previewToggled') || (preview.env === 'xs' || preview.env === 'sm');
52
+ const previewContainer = postContainer.querySelector('.preview-container');
53
+ const writeContainer = postContainer.querySelector('.write-container');
54
+
55
+ if (!toggler) {
56
+ return;
65
57
  }
66
58
 
67
59
  function togglePreview(show) {
68
- if (preview.env === 'xs' || preview.env === 'sm') {
69
- previewContainer.toggleClass('hide', false);
70
- writeContainer.toggleClass('maximized', false);
71
- showBtn.toggleClass('hide', true);
72
- previewContainer.toggleClass('hidden-xs hidden-sm', !show);
73
- writeContainer.toggleClass('hidden-xs hidden-sm', show);
60
+ if (isMobile) {
61
+ previewContainer.classList.toggle('hide', false);
62
+ writeContainer.classList.toggle('maximized', false);
63
+ previewContainer.classList.toggle('d-none', !show);
64
+ previewContainer.classList.toggle('d-flex', show);
65
+ writeContainer.classList.toggle('d-flex', !show);
66
+ writeContainer.classList.toggle('d-none', show);
74
67
 
75
68
  // Render preview once on mobile
76
69
  if (show) {
77
- preview.render(postContainer);
70
+ preview.render($postContainer);
78
71
  }
79
72
  } else {
80
- previewContainer.toggleClass('hide', !show);
81
- writeContainer.toggleClass('maximized', !show);
82
- showBtn.toggleClass('hide', show);
73
+ previewContainer.classList.toggle('hide', !show);
74
+ writeContainer.classList.toggle('w-50', show);
75
+ writeContainer.classList.toggle('w-100', !show);
76
+
77
+ localStorage[show ? 'removeItem' : 'setItem']('composer:previewToggled', true);
83
78
  }
84
79
 
85
- preview.matchScroll(postContainer);
80
+ preview.matchScroll($postContainer);
86
81
  }
87
82
  preview.toggle = togglePreview;
88
83
 
89
- hideBtn.on('click', function () {
90
- hidePreview();
91
- postContainer.find('.write').focus();
92
- });
93
- showBtn.on('click', function () {
94
- showPreview();
95
- postContainer.find('.write').focus();
84
+ toggler.addEventListener('click', (e) => {
85
+ if (e.button !== 0) {
86
+ return;
87
+ }
88
+
89
+ show = !show;
90
+ togglePreview(show);
96
91
  });
97
92
 
98
- if (localStorage.getItem('composer:previewToggled') || (preview.env === 'xs' || preview.env === 'sm')) {
99
- hidePreview();
100
- } else {
101
- showPreview();
102
- }
93
+ togglePreview(show);
103
94
  };
104
95
 
105
96
  return preview;
@@ -181,6 +181,10 @@ define('composer/resize', ['taskbar'], function (taskbar) {
181
181
 
182
182
  $resizer
183
183
  .on('mousedown', function (e) {
184
+ if (e.button !== 0) {
185
+ return;
186
+ }
187
+
184
188
  e.preventDefault();
185
189
  resizeStart(e);
186
190
  })
@@ -33,7 +33,7 @@ define('composer/scheduler', ['benchpress', 'bootbox', 'alerts'], function (Benc
33
33
  submitBtn.defaultText = submitBtn.el.lastChild.textContent;
34
34
  submitBtn.activeText = submitBtn.el.getAttribute('data-text-variant');
35
35
 
36
- displayBtns.forEach(el => el.addEventListener('click', openModal));
36
+ displayBtnCons.forEach(el => el.addEventListener('click', openModal));
37
37
  };
38
38
 
39
39
  scheduler.getTimestamp = function () {
@@ -291,6 +291,10 @@ define('composer', [
291
291
  postData.body = data.body;
292
292
  postData.modified = true;
293
293
  }
294
+ if (data.title) {
295
+ postData.title = data.title;
296
+ postData.modified = true;
297
+ }
294
298
  push(postData);
295
299
  });
296
300
  };
@@ -572,12 +576,14 @@ define('composer', [
572
576
  }
573
577
 
574
578
  function handleHelp(postContainer) {
575
- var helpBtn = postContainer.find('.help');
579
+ var helpBtn = postContainer.find('[data-action="help"]');
576
580
  socket.emit('plugins.composer.renderHelp', function (err, html) {
577
581
  if (!err && html && html.length > 0) {
578
- helpBtn.removeClass('hidden');
579
582
  helpBtn.on('click', function () {
580
- bootbox.alert(html);
583
+ bootbox.dialog({
584
+ size: 'large',
585
+ message: html,
586
+ });
581
587
  });
582
588
  }
583
589
  });
@@ -11,12 +11,6 @@
11
11
  right: 0;
12
12
  left: 0;
13
13
 
14
- .composer-container {
15
- height: 100%;
16
- display: flex;
17
- flex-direction: column;
18
- }
19
-
20
14
  .mobile-navbar {
21
15
  position: static;
22
16
  min-height: 40px;
@@ -46,30 +40,10 @@
46
40
  }
47
41
 
48
42
  .title-container {
49
- display: flex;
50
- border-bottom: 1px solid $border-color;
51
- margin: 0;
52
-
53
- > div[data-component="composer/title"] {
54
- flex: 1;
55
- }
56
-
57
43
  > div[data-component="composer/handle"] {
58
44
  flex: 0.33;
59
45
  }
60
46
 
61
- .title, .handle {
62
- background: transparent;
63
- color: $body-color;
64
- display: block;
65
- margin: 0;
66
- padding: 8px;
67
- font-size: 18px;
68
- border: 0;
69
- box-shadow: none;
70
- overflow: hidden;
71
- }
72
-
73
47
  .category-list-container {
74
48
 
75
49
  [component="category-selector"] {
@@ -85,10 +59,6 @@
85
59
  padding: 0 2rem;
86
60
  }
87
61
 
88
- .composer-submit, .composer-discard {
89
- min-width: 106px;
90
- }
91
-
92
62
  .action-bar {
93
63
  .dropdown-menu:empty {
94
64
  & ~ .dropdown-toggle {
@@ -98,26 +68,6 @@
98
68
  }
99
69
  }
100
70
 
101
- .display-scheduler {
102
- display: flex;
103
- align-items: center;
104
- margin-right: 1em;
105
-
106
- > i {
107
- font-size: 30px;
108
- display: inline-block;
109
- cursor: pointer;
110
-
111
- &.active {
112
- animation: 300ms ease forwards pulse;
113
- }
114
- }
115
- }
116
-
117
- .category-tag-row {
118
- margin: 0;
119
- }
120
-
121
71
  .formatting-bar {
122
72
  margin: 0;
123
73
 
@@ -129,25 +79,7 @@
129
79
  }
130
80
 
131
81
  .formatting-group {
132
- padding: 0;
133
- margin: 0;
134
- overflow-x: auto;
135
- white-space: nowrap;
136
- display: block;
137
- list-style: none;
138
-
139
82
  li {
140
- display: inline-block;
141
- padding: 10px 15px;
142
- cursor: pointer;
143
- position: relative;
144
-
145
- &:focus, &:hover {
146
- outline: none;
147
- color: $dropdown-link-hover-color;
148
- background-color: $dropdown-link-hover-bg;
149
- }
150
-
151
83
  &[data-format="thumbs"][data-count]:after {
152
84
  content: attr(data-count);
153
85
  background: $info;
@@ -164,69 +96,6 @@
164
96
  }
165
97
  }
166
98
 
167
- .write-preview-container {
168
- flex: 2;
169
- display: flex;
170
- overflow: hidden;
171
- }
172
-
173
- .write-container, .preview-container {
174
- display: flex;
175
- flex: 1;
176
- position: relative;
177
-
178
- .help-text {
179
- text-transform: uppercase;
180
- position: absolute;
181
- right: 35px;
182
- top: 8px;
183
- font-size: 10px;
184
- z-index: 1;
185
- }
186
- }
187
-
188
- .write-container {
189
- &.maximized {
190
- width: 100%;
191
- }
192
- }
193
-
194
- .preview-container {
195
- word-wrap: break-word;
196
- max-width: 50%;
197
- }
198
-
199
- .write, .preview {
200
- width: 100%;
201
- font-size: 16px;
202
- @include border-radius(0);
203
- resize: none;
204
- overflow: auto;
205
- padding: 25px 10px;
206
- margin: 0;
207
- }
208
-
209
- .write {
210
- border: none;
211
- border-top: 1px solid $border-color;
212
- border-bottom: 1px solid $border-color;
213
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
214
- }
215
-
216
- .preview {
217
- -webkit-touch-callout: default;
218
- user-select: text;
219
- }
220
-
221
- .help {
222
- @include pointer;
223
- }
224
-
225
- .toggle-preview {
226
- margin-left: 20px;
227
- @include pointer;
228
- }
229
-
230
99
  .tags-container {
231
100
  [component="composer/tag/dropdown"] {
232
101
  .dropdown-menu {
@@ -272,46 +141,17 @@
272
141
  }
273
142
 
274
143
  .resizer {
275
- display: none;
276
- position: absolute;
277
- left: 10%;
278
- width: 80%;
279
- top: 0px;
280
- height: 0;
281
-
282
- @include pointer;
144
+ background: linear-gradient(transparent, #fff);
145
+ margin-left: calc($spacer * -0.5);
146
+ padding-left: $spacer;
283
147
 
284
148
  .trigger {
285
- position: relative;
286
- display: block;
287
- top: -20px;
288
- margin: 0 auto;
289
- margin-left: 20px;
290
- line-height: 26px;
291
- @include transition(filter .15s linear);
149
+ cursor: ns-resize;
292
150
 
293
- &:hover {
294
- filter: invert(100%);
295
- cursor: ns-resize;
296
- }
297
-
298
- i {
299
- width: 32px;
300
- height: 32px;
301
- background: #333;
302
- border: 1px solid #333;
303
- border-radius: 50%;
304
-
305
- position: relative;
306
-
307
- color: #FFF;
308
- font-size: 16px;
309
-
310
- &:before {
311
- content: fa-content($fa-var-arrows-alt-v);
312
- position: relative;
313
- top: 25%;
314
- }
151
+ .handle {
152
+ border-top-left-radius: 50%;
153
+ border-top-right-radius: 50%;
154
+ border-bottom: 0 !important;
315
155
  }
316
156
  }
317
157
  }
@@ -366,33 +206,35 @@
366
206
  }
367
207
 
368
208
  &.resizable.maximized {
369
- .resizer .trigger i {
370
- &:before {
371
- content: fa-content($fa-var-chevron-down);
209
+ .resizer {
210
+ top: 0 !important;
211
+ background: transparent;
212
+
213
+ .trigger {
214
+ .handle {
215
+ border-top-left-radius: 0%;
216
+ border-top-right-radius: 0%;
217
+ border-bottom-left-radius: 50%;
218
+ border-bottom-right-radius: 50%;
219
+ border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;
220
+ }
221
+
222
+ i {
223
+ &:before {
224
+ content: fa-content($fa-var-chevron-down);
225
+ }
226
+ }
372
227
  }
373
228
  }
374
-
375
- box-shadow: none;
376
229
  }
377
230
 
378
231
  .draft-icon {
379
232
  font-family: 'FontAwesome';
380
233
  color: $success;
381
- margin: 0 1em;
382
234
  opacity: 0;
383
235
 
384
236
  &::before {
385
237
  content: fa-content($fa-var-save);
386
- position: relative;
387
- top: 25%;
388
- }
389
-
390
- &::after {
391
- content: fa-content($fa-var-check);
392
- position: relative;
393
- top: 18px;
394
- font-size: 0.7em;
395
- left: -15%;
396
238
  }
397
239
 
398
240
  &.active {
@@ -488,10 +330,6 @@
488
330
  }
489
331
  }
490
332
 
491
- .toggle-preview.hide {
492
- display: inline-block !important;
493
- }
494
-
495
333
  .preview-container {
496
334
  max-width: initial;
497
335
  }
@@ -14,50 +14,7 @@
14
14
  display: flex;
15
15
  }
16
16
 
17
- .title-container {
18
- border: 0;
19
-
20
- .title, .handle {
21
- font-size: 22px;
22
- padding: 4px;
23
- }
24
- }
25
-
26
- .formatting-bar .formatting-group {
27
- display: inline-block;
28
- }
29
-
30
- &.resizable {
31
- box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.5);
32
-
33
- padding-top: 30px;
34
- padding-left: 15px;
35
- padding-right: 15px;
36
- }
37
-
38
- .category-tag-row {
39
- margin-top: 5px;
40
- margin-bottom: 8px;
41
- }
42
-
43
- .write-preview-container {
44
- margin-bottom: 15px;
45
- }
46
-
47
- .write, .preview {
48
- padding: 20px;
49
- }
50
-
51
- .write {
52
- border: 1px solid $border-color;
53
- }
54
-
55
- .tags-container {
56
- margin-top: 8px - 15px;
57
- margin-bottom: 8px;
58
-
59
- .bootstrap-tagsinput {
60
- padding: 0;
61
- }
62
- }
17
+ // &.resizable {
18
+ // box-shadow: 0px -20px 20px rgba(255, 255, 255);
19
+ // }
63
20
  }
@@ -13,10 +13,6 @@ body.page-compose {
13
13
  height: 100%;
14
14
  z-index: initial;
15
15
  position: static;
16
-
17
- .display-scheduler {
18
- margin: 0 0 0 .6em;
19
- }
20
16
  }
21
17
 
22
18
  .zen-mode .page-compose .composer {
@@ -32,10 +32,6 @@ html.zen-mode {
32
32
  .title-container {
33
33
  display: none;
34
34
  }
35
-
36
- .category-tag-row {
37
- margin-top: 3px;
38
- }
39
35
  }
40
36
 
41
37
  @include media-breakpoint-up(md) {
@@ -1,6 +1,6 @@
1
- <div component="composer" class="composer<!-- IF resizable --> resizable<!-- ENDIF resizable --><!-- IF !isTopicOrMain --> reply<!-- ENDIF !isTopicOrMain -->">
1
+ <div component="composer" class="composer pt-2 px-2<!-- IF resizable --> resizable<!-- ENDIF resizable --><!-- IF !isTopicOrMain --> reply<!-- ENDIF !isTopicOrMain -->">
2
2
 
3
- <div class="composer-container">
3
+ <div class="composer-container d-flex flex-column h-100">
4
4
  <!-- mobile header -->
5
5
  <nav class="navbar fixed-top mobile-navbar hidden-md hidden-lg text-bg-primary flex-nowrap">
6
6
  <div class="btn-group">
@@ -35,6 +35,12 @@
35
35
 
36
36
  <div class="imagedrop"><div>[[topic:composer.drag_and_drop_images]]</div></div>
37
37
 
38
- <div class="resizer"><div class="trigger text-center"><i class="fa"></i></div></div>
38
+ <div class="resizer position-absolute w-100 bottom-100 pe-3 border-bottom">
39
+ <div class="trigger text-center">
40
+ <div class="handle d-inline-block px-2 py-1 border bg-body">
41
+ <i class="fa fa-fw fa-up-down"></i>
42
+ </div>
43
+ </div>
44
+ </div>
39
45
  </div>
40
46
  </div>
@@ -1,30 +1,46 @@
1
- <div class="category-tag-row">
2
- <div class="btn-toolbar formatting-bar">
3
- <ul class="formatting-group">
4
- <!-- BEGIN formatting -->
5
- <!-- IF formatting.spacer -->
6
- <li class="spacer"></li>
7
- <!-- ELSE -->
8
- {{{ if (./visibility.desktop && ((isTopicOrMain && ./visibility.main) || (!isTopicOrMain && ./visibility.reply))) }}}
9
- <li tabindex="-1" data-format="{formatting.name}" title="{formatting.title}"><i class="{formatting.className}"></i></li>
10
- {{{ end }}}
11
- <!-- ENDIF formatting.spacer -->
12
- <!-- END formatting -->
1
+ <nav class="navbar navbar-expand formatting-bar">
2
+ <ul class="formatting-group navbar-nav me-auto gap-2">
3
+ <!-- BEGIN formatting -->
4
+ <!-- IF formatting.spacer -->
5
+ <li class="nav-item small spacer"></li>
6
+ <!-- ELSE -->
7
+ {{{ if (./visibility.desktop && ((isTopicOrMain && ./visibility.main) || (!isTopicOrMain && ./visibility.reply))) }}}
8
+ <li class="nav-item small">
9
+ <a href="#" class="nav-link" tabindex="-1" data-format="{formatting.name}" title="{formatting.title}">
10
+ <i class="{formatting.className}"></i>
11
+ </a>
12
+ </li>
13
+ {{{ end }}}
14
+ <!-- ENDIF formatting.spacer -->
15
+ <!-- END formatting -->
13
16
 
14
- <!-- IF privileges.upload:post:image -->
15
- <li class="img-upload-btn" data-format="picture" tabindex="-1" title="[[modules:composer.upload-picture]]">
17
+ <!-- IF privileges.upload:post:image -->
18
+ <li class="img-upload-btn nav-item small">
19
+ <a href="#" class="nav-link" data-format="picture" tabindex="-1" title="[[modules:composer.upload-picture]]">
16
20
  <i class="fa fa-file-image-o"></i>
17
- </li>
18
- <!-- ENDIF privileges.upload:post:image -->
19
- <!-- IF privileges.upload:post:file -->
20
- <li class="file-upload-btn" data-format="upload" tabindex="-1" title="[[modules:composer.upload-file]]">
21
+ </a>
22
+ </li>
23
+ <!-- ENDIF privileges.upload:post:image -->
24
+ <!-- IF privileges.upload:post:file -->
25
+ <li class="file-upload-btn nav-item small">
26
+ <a href="#" class="nav-link" data-format="upload" tabindex="-1" title="[[modules:composer.upload-file]]">
21
27
  <i class="fa fa-file-o"></i>
22
- </li>
23
- <!-- ENDIF privileges.upload:post:file -->
28
+ </a>
29
+ </li>
30
+ <!-- ENDIF privileges.upload:post:file -->
31
+
32
+ <form id="fileForm" method="post" enctype="multipart/form-data">
33
+ <input type="file" id="files" name="files[]" multiple class="gte-ie9 hide"/>
34
+ </form>
35
+ </ul>
24
36
 
25
- <form id="fileForm" method="post" enctype="multipart/form-data">
26
- <input type="file" id="files" name="files[]" multiple class="gte-ie9 hide"/>
27
- </form>
28
- </ul>
29
- </div>
30
- </div>
37
+ <div class="draft-icon mx-2 hidden-xs hidden-sm"></div>
38
+ <button class="btn btn-sm btn-link text-body fw-semibold" data-action="preview">
39
+ <i class="fa fa-eye"></i>
40
+ <span class="d-none d-md-inline">[[modules:composer.show_preview]]</span>
41
+ </button>
42
+ <button class="btn btn-sm btn-link text-body fw-semibold" data-action="help">
43
+ <i class="fa fa-question"></i>
44
+ <span class="d-none d-md-inline">[[modules:composer.help]]</span>
45
+ </button>
46
+ </nav>
@@ -1,4 +1,4 @@
1
- <div class="title-container">
1
+ <div class="title-container d-flex">
2
2
  {{{ if isTopic }}}
3
3
  <div class="category-list-container hidden-sm hidden-xs align-self-center">
4
4
  <!-- IMPORT partials/category-selector.tpl -->
@@ -7,14 +7,14 @@
7
7
 
8
8
  {{{ if showHandleInput }}}
9
9
  <div data-component="composer/handle">
10
- <input class="handle form-control h-100" type="text" tabindex="1" placeholder="[[topic:composer.handle_placeholder]]" value="{handle}" />
10
+ <input class="handle form-control h-100 border-0 shadow-none" type="text" tabindex="1" placeholder="[[topic:composer.handle_placeholder]]" value="{handle}" />
11
11
  </div>
12
12
  {{{ end }}}
13
- <div data-component="composer/title" class="position-relative">
13
+ <div data-component="composer/title" class="position-relative flex-grow-1">
14
14
  {{{ if isTopicOrMain }}}
15
- <input class="title form-control h-100" type="text" tabindex="1" placeholder="[[topic:composer.title_placeholder]]" value="{topicTitle}"/>
15
+ <input class="title form-control h-100 rounded-1 shadow-none" type="text" tabindex="1" placeholder="[[topic:composer.title_placeholder]]" value="{topicTitle}"/>
16
16
  {{{ else }}}
17
- <span class="title h-100">{{{ if isEditing }}}[[topic:composer.editing]]{{{ else }}}[[topic:composer.replying_to, "{topicTitle}"]]{{{ end }}}</span>
17
+ <span class="title h-100 text-truncate">{{{ if isEditing }}}[[topic:composer.editing]]{{{ else }}}[[topic:composer.replying_to, "{topicTitle}"]]{{{ end }}}</span>
18
18
  {{{ end }}}
19
19
  <div id="quick-search-container" class="quick-search-container mt-2 dropdown-menu d-block p-2 hidden">
20
20
  <div class="text-center loading-indicator"><i class="fa fa-spinner fa-spin"></i></div>
@@ -22,22 +22,22 @@
22
22
  </div>
23
23
  </div>
24
24
 
25
- <div class="float-end draft-icon hidden-xs hidden-sm"></div>
26
-
27
- <div class="display-scheduler float-end hidden-sm hidden-xs{{{ if !canSchedule }}} hidden{{{ end }}}">
28
- <i class="fa fa-clock-o"></i>
29
- </div>
30
-
31
- <div class="btn-group float-end action-bar hidden-sm hidden-xs">
32
- <button class="btn btn-outline-secondary composer-discard" data-action="discard" tabindex="-1"><i class="fa fa-times"></i> [[topic:composer.discard]]</button>
33
-
34
- <button class="btn btn-primary composer-submit" data-action="post" tabindex="6" data-text-variant=" [[topic:composer.schedule]]"><i class="fa fa-check"></i> [[topic:composer.submit]]</button>
35
- {{{ if submitOptions.length }}}
36
- <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
37
- <span class="caret"></span>
38
- <span class="sr-only">[[topic:composer.additional-options]]</span>
39
- </button>
40
- <ul class="dropdown-menu">{{{ each submitOptions }}}<li><a class="dropdown-item" href="#" data-action="{./action}">{./text}</a></li>{{{ end }}}</ul>
41
- {{{ end }}}
25
+ <div class="d-flex action-bar hidden-sm hidden-xs align-items-center">
26
+ <button class="btn btn-sm btn-link text-body fw-semibold" data-action="hide" tabindex="-1"><i class="fa fa-angle-down"></i> [[topic:composer.hide]]</button>
27
+ <button class="btn btn-sm btn-link composer-discard text-body fw-semibold" data-action="discard" tabindex="-1"><i class="fa fa-trash"></i> [[topic:composer.discard]]</button>
28
+ <div class="btn-group btn-group-sm">
29
+ <button class="btn btn-primary composer-submit fw-bold" data-action="post" tabindex="6" data-text-variant=" [[topic:composer.schedule]]"><i class="fa fa-check"></i> [[topic:composer.submit]]</button>
30
+ {{{ if (submitOptions.length || canSchedule) }}}
31
+ <button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
32
+ <i class="fa fa-caret-down"></i>
33
+ <span class="sr-only">[[topic:composer.additional-options]]</span>
34
+ </button>
35
+ <ul class="dropdown-menu">
36
+ <li><a class="dropdown-item display-scheduler ">Post Later</a></li>
37
+ {{{ each submitOptions }}}
38
+ <li><a class="dropdown-item" href="#" data-action="{./action}">{./text}</a></li>
39
+ {{{ end }}}</ul>
40
+ {{{ end }}}
41
+ </div>
42
42
  </div>
43
43
  </div>
@@ -1,16 +1,9 @@
1
- <div class="write-preview-container">
2
- <div class="write-container me-1">
3
- <div class="help-text text-black-50 ">
4
- <span class="help hidden">[[modules:composer.compose]] <i class="fa fa-question-circle"></i></span>
5
- <span class="toggle-preview hide">[[modules:composer.show_preview]]</span>
6
- </div>
1
+ <div class="write-preview-container d-flex gap-2 flex-grow-1">
2
+ <div class="write-container d-flex d-md-flex w-50">
7
3
  <div class="float-end draft-icon hidden-md hidden-lg"></div>
8
- <textarea class="write" tabindex="4" placeholder="[[modules:composer.textarea.placeholder]]">{body}</textarea>
4
+ <textarea class="write shadow-none rounded-1 w-100 form-control" tabindex="4" placeholder="[[modules:composer.textarea.placeholder]]">{body}</textarea>
9
5
  </div>
10
- <div class="hidden-sm hidden-xs preview-container ms-1">
11
- <div class="help-text text-black-50">
12
- <span class="toggle-preview">[[modules:composer.hide_preview]]</span>
13
- </div>
14
- <div class="preview card card-body bg-light"></div>
6
+ <div class="preview-container d-none d-md-flex w-50">
7
+ <div class="preview card card-body bg-light rounded-1"></div>
15
8
  </div>
16
9
  </div>