diff options
Diffstat (limited to 'view/tpl')
-rw-r--r-- | view/tpl/cal_calendar.tpl | 8 | ||||
-rw-r--r-- | view/tpl/cdav_calendar.tpl | 17 | ||||
-rw-r--r-- | view/tpl/cdav_widget_calendar.tpl | 26 | ||||
-rw-r--r-- | view/tpl/channel_activities.tpl | 4 | ||||
-rw-r--r-- | view/tpl/cloud_directory.tpl | 2 | ||||
-rw-r--r-- | view/tpl/connections.tpl | 1 | ||||
-rw-r--r-- | view/tpl/conv_item.tpl | 56 | ||||
-rw-r--r-- | view/tpl/conv_list.tpl | 58 | ||||
-rw-r--r-- | view/tpl/messages_widget.tpl | 100 | ||||
-rw-r--r-- | view/tpl/navbar_default.tpl | 38 | ||||
-rw-r--r-- | view/tpl/notifications_widget.tpl | 65 | ||||
-rw-r--r-- | view/tpl/pinned_item.tpl | 74 | ||||
-rw-r--r-- | view/tpl/search_item.tpl | 58 | ||||
-rw-r--r-- | view/tpl/settings_account.tpl | 1 | ||||
-rw-r--r-- | view/tpl/totp.tpl | 27 | ||||
-rw-r--r-- | view/tpl/totp_setup.tpl | 64 |
16 files changed, 422 insertions, 177 deletions
diff --git a/view/tpl/cal_calendar.tpl b/view/tpl/cal_calendar.tpl index a928e98f6..68ec318bd 100644 --- a/view/tpl/cal_calendar.tpl +++ b/view/tpl/cal_calendar.tpl @@ -4,7 +4,7 @@ var calendar; $(document).ready(function() { var calendarEl = document.getElementById('calendar'); calendar = new FullCalendar.Calendar(calendarEl, { - plugins: [ 'dayGrid' ], + eventSources: [ {{$sources}} ], timeZone: '{{$timezone}}', @@ -12,16 +12,12 @@ $(document).ready(function() { locale: '{{$lang}}', eventTextColor: 'white', - header: false, + headerToolbar: false, height: 'auto', firstDay: {{$first_day}}, - monthNames: aStr['monthNames'], - monthNamesShort: aStr['monthNamesShort'], - dayNames: aStr['dayNames'], - dayNamesShort: aStr['dayNamesShort'], allDayText: aStr['allday'], eventClick: function(info) { diff --git a/view/tpl/cdav_calendar.tpl b/view/tpl/cdav_calendar.tpl index 2d6853513..edfa2a422 100644 --- a/view/tpl/cdav_calendar.tpl +++ b/view/tpl/cdav_calendar.tpl @@ -14,15 +14,12 @@ var contact_deny = []; var group_deny = []; var resource = {{$resource}}; -var default_view = resource !== null ? 'timeGridDay' : 'dayGridMonth'; -var default_date = resource !== null ? new Date(resource.dtstart) : new Date(); - var allday; $(document).ready(function() { var calendarEl = document.getElementById('calendar'); calendar = new FullCalendar.Calendar(calendarEl, { - plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ], + eventSources: [ {{$sources}} ], timeZone: '{{$timezone}}', @@ -30,15 +27,12 @@ $(document).ready(function() { locale: '{{$lang}}', eventTextColor: 'white', - header: false, + headerToolbar: false, height: 'auto', firstDay: {{$first_day}}, - defaultView: default_view, - defaultDate: default_date, - weekNumbers: true, navLinks: true, @@ -52,10 +46,6 @@ $(document).ready(function() { changeView('timeGridWeek'); }, - monthNames: aStr['monthNames'], - monthNamesShort: aStr['monthNamesShort'], - dayNames: aStr['dayNames'], - dayNamesShort: aStr['dayNamesShort'], allDayText: aStr['allday'], snapDuration: '00:05:00', @@ -380,11 +370,8 @@ $(document).ready(function() { $('#event_submit').html('{{$update}}'); } - if(default_view === 'dayGridMonth'); - $('#id_dtstart_wrapper, #id_dtend_wrapper, #id_timezone_select_wrapper').hide(); }); - function changeView(viewName) { calendar.changeView(viewName); diff --git a/view/tpl/cdav_widget_calendar.tpl b/view/tpl/cdav_widget_calendar.tpl index c27f4789e..b076a3320 100644 --- a/view/tpl/cdav_widget_calendar.tpl +++ b/view/tpl/cdav_widget_calendar.tpl @@ -3,9 +3,9 @@ {{foreach $channel_calendars as $channel_calendar}} <div id="calendar-{{$channel_calendar.calendarid}}"> <div class="ml-3{{if !$channel_calendar@last}} mb-3{{/if}}"> - <i id="calendar-btn-{{$channel_calendar.calendarid}}" class="fa {{if $channel_calendar.switch}}fa-calendar-check-o{{else}}fa-calendar-o{{/if}} generic-icons fakelink" onclick="add_remove_json_source('{{$channel_calendar.json_source}}', '{{$channel_calendar.color}}', {{$channel_calendar.editable}})" style="color: {{$channel_calendar.color}};"></i>{{$channel_calendar.displayname}} + <i id="calendar-btn-{{$channel_calendar.calendarid}}" class="fa {{if $channel_calendar.switch}}fa-calendar-check-o{{else}}fa-calendar-o{{/if}} generic-icons cursor-pointer" onclick="add_remove_json_source('{{$channel_calendar.json_source}}', '{{$channel_calendar.color}}', {{$channel_calendar.editable}})" style="color: {{$channel_calendar.color}};"></i>{{$channel_calendar.displayname}} <div class="float-end"> - <a href="#" onclick="exportDate(); return false;"><i id="download-icon" class="fa fa-cloud-download fakelink generic-icons-right"></i></a> + <a class="text-reset" href="#" onclick="exportDate(); return false;"><i id="download-icon" class="fa fa-cloud-download cursor-pointer generic-icons-right"></i></a> </div> </div> </div> @@ -18,12 +18,12 @@ {{foreach $my_calendars as $calendar}} <div id="calendar-{{$calendar.calendarid}}"> <div class="ml-3{{if !$calendar@last}} mb-3{{/if}}"> - <i id="calendar-btn-{{$calendar.calendarid}}" class="fa {{if $calendar.switch}}fa-calendar-check-o{{else}}fa-calendar-o{{/if}} generic-icons fakelink" onclick="add_remove_json_source('{{$calendar.json_source}}', '{{$calendar.color}}', {{$calendar.editable}})" style="color: {{$calendar.color}};"></i>{{$calendar.displayname}} + <i id="calendar-btn-{{$calendar.calendarid}}" class="fa {{if $calendar.switch}}fa-calendar-check-o{{else}}fa-calendar-o{{/if}} generic-icons cursor-pointer" onclick="add_remove_json_source('{{$calendar.json_source}}', '{{$calendar.color}}', {{$calendar.editable}})" style="color: {{$calendar.color}};"></i>{{$calendar.displayname}} <div class="float-end"> - <i id="edit-icon" class="fa fa-pencil fakelink generic-icons" onclick="openClose('edit-calendar-{{$calendar.calendarid}}')"></i> - <a href="/cdav/calendars/{{$calendar.ownernick}}/{{$calendar.uri}}/?export"><i id="download-icon" class="fa fa-cloud-download fakelink generic-icons"></i></a> - <i id="share-icon" class="fa fa-share-alt fakelink generic-icons" onclick="openClose('share-calendar-{{$calendar.calendarid}}')"></i> - <a href="#" onclick="var drop = dropItem('/cdav/calendar/drop/{{$calendar.calendarid}}/{{$calendar.instanceid}}', '#calendar-{{$calendar.calendarid}}'); if(drop) { add_remove_json_source('{{$calendar.json_source}}', '{{$calendar.color}}', {{$calendar.editable}}, 'drop'); } return false;"><i class="fa fa-trash-o drop-icons"></i></a> + <i id="edit-icon" class="fa fa-pencil cursor-pointer generic-icons" onclick="openClose('edit-calendar-{{$calendar.calendarid}}')"></i> + <a class="text-reset" href="/cdav/calendars/{{$calendar.ownernick}}/{{$calendar.uri}}/?export"><i id="download-icon" class="fa fa-cloud-download cursor-pointer generic-icons"></i></a> + <i id="share-icon" class="fa fa-share-alt cursor-pointer generic-icons" onclick="openClose('share-calendar-{{$calendar.calendarid}}')"></i> + <a class="text-reset" href="#" onclick="var drop = dropItem('/cdav/calendar/drop/{{$calendar.calendarid}}/{{$calendar.instanceid}}', '#calendar-{{$calendar.calendarid}}'); if(drop) { add_remove_json_source('{{$calendar.json_source}}', '{{$calendar.color}}', {{$calendar.editable}}, 'drop'); } return false;"><i class="fa fa-trash-o drop-icons"></i></a> </div> <div id="share-calendar-{{$calendar.calendarid}}" class="sub-menu" style="display: none; border-color: {{$calendar.color}};"> {{if $calendar.sharees}} @@ -31,7 +31,7 @@ <div id="sharee-{{$calendar.calendarid}}-{{$sharee@iteration}}" class="mb-3"> <i class="fa fa-share generic-icons"></i>{{$sharee.name}} {{$sharee.access}} <div class="float-end"> - <a href="#" onclick="dropItem('/cdav/calendar/dropsharee/{{$calendar.calendarid}}/{{$calendar.instanceid}}/{{$sharee.hash}}', '#sharee-{{$calendar.calendarid}}-{{$sharee@iteration}}'); return false;"><i class="fa fa-trash-o drop-icons"></i></a> + <a class="text-reset" href="#" onclick="dropItem('/cdav/calendar/dropsharee/{{$calendar.calendarid}}/{{$calendar.instanceid}}/{{$sharee.hash}}', '#sharee-{{$calendar.calendarid}}-{{$sharee@iteration}}'); return false;"><i class="fa fa-trash-o drop-icons"></i></a> </div> </div> {{/foreach}} @@ -80,10 +80,10 @@ <h3>{{$shared_calendars_label}}</h3> {{foreach $shared_calendars as $calendar}} <div id="shared-calendar-{{$calendar.calendarid}}" class="ml-3{{if !$calendar@last}} mb-3{{/if}}"> - <i id="calendar-btn-{{$calendar.calendarid}}" class="fa {{if $calendar.switch}}{{if $calendar.access == 'read-write'}}fa-calendar-check-o{{else}}fa-calendar-times-o{{/if}}{{else}}fa-calendar-o{{/if}} generic-icons fakelink" onclick="add_remove_json_source('{{$calendar.json_source}}', '{{$calendar.color}}', {{$calendar.editable}}, {{if $calendar.access == 'read-write'}}'fa-calendar-check-o'{{else}}'fa-calendar-times-o'{{/if}})" style="color: {{$calendar.color}};"></i>{{$calendar.displayname}} ({{$calendar.sharer}}) + <i id="calendar-btn-{{$calendar.calendarid}}" class="fa {{if $calendar.switch}}{{if $calendar.access == 'read-write'}}fa-calendar-check-o{{else}}fa-calendar-times-o{{/if}}{{else}}fa-calendar-o{{/if}} generic-icons cursor-pointer" onclick="add_remove_json_source('{{$calendar.json_source}}', '{{$calendar.color}}', {{$calendar.editable}}, {{if $calendar.access == 'read-write'}}'fa-calendar-check-o'{{else}}'fa-calendar-times-o'{{/if}})" style="color: {{$calendar.color}};"></i>{{$calendar.displayname}} ({{$calendar.sharer}}) <div class="float-end"> - <a href="/cdav/calendars/{{$calendar.ownernick}}/{{$calendar.uri}}/?export"><i id="download-icon" class="fa fa-cloud-download fakelink generic-icons"></i></a> - <a href="#" onclick="var drop = dropItem('/cdav/calendar/drop/{{$calendar.calendarid}}/{{$calendar.instanceid}}', '#shared-calendar-{{$calendar.calendarid}}'); if(drop) { add_remove_json_source('{{$calendar.json_source}}', '{{$calendar.color}}', {{$calendar.editable}}, 'drop'); } return false;"><i class="fa fa-trash-o drop-icons"></i></a> + <a class="text-reset" href="/cdav/calendars/{{$calendar.ownernick}}/{{$calendar.uri}}/?export"><i id="download-icon" class="fa fa-cloud-download cursor-pointer generic-icons"></i></a> + <a class="text-reset" href="#" onclick="var drop = dropItem('/cdav/calendar/drop/{{$calendar.calendarid}}/{{$calendar.instanceid}}', '#shared-calendar-{{$calendar.calendarid}}'); if(drop) { add_remove_json_source('{{$calendar.json_source}}', '{{$calendar.color}}', {{$calendar.editable}}, 'drop'); } return false;"><i class="fa fa-trash-o drop-icons"></i></a> </div> </div> {{/foreach}} @@ -94,7 +94,7 @@ <h3>{{$tools_label}}</h3> <div class="nav nav-pills flex-column"> <li class="nav-item"> - <a class="nav-link" href="#" onclick="openClose('create-calendar'); return false;"><i class="fa fa-calendar-plus-o generic-icons"></i> {{$create_label}}</a> + <a class="nav-link text-reset" href="#" onclick="openClose('create-calendar'); return false;"><i class="fa fa-calendar-plus-o generic-icons"></i> {{$create_label}}</a> </li> <div id="create-calendar" class="sub-menu-wrapper"> <div class="sub-menu"> @@ -111,7 +111,7 @@ </div> </div> <li class="nav-item"> - <a class="nav-link" href="#" onclick="openClose('upload-form'); return false;"><i class="fa fa-cloud-upload generic-icons"></i> {{$import_label}}</a> + <a class="nav-link text-reset" href="#" onclick="openClose('upload-form'); return false;"><i class="fa fa-cloud-upload generic-icons"></i> {{$import_label}}</a> </li> <div id="upload-form" class="sub-menu-wrapper"> <div class="sub-menu"> diff --git a/view/tpl/channel_activities.tpl b/view/tpl/channel_activities.tpl index 242fc519a..3ec37e235 100644 --- a/view/tpl/channel_activities.tpl +++ b/view/tpl/channel_activities.tpl @@ -5,8 +5,8 @@ {{foreach $items as $i}} <div class="col"> <div class="card"> - <a href="{{$i.url}}" class="text-dark"> - <div class="card-body"> + <a href="{{$i.url}}" class="text-reset"> + <div class="card-body clearfix"> {{if $i.title}} <strong>{{$i.title}}</strong> <hr> diff --git a/view/tpl/cloud_directory.tpl b/view/tpl/cloud_directory.tpl index a851eb203..587adaeea 100644 --- a/view/tpl/cloud_directory.tpl +++ b/view/tpl/cloud_directory.tpl @@ -175,7 +175,7 @@ {{if $is_owner}} <a id="cloud-tool-share-btn-{{$item.attach_id}}" class="dropdown-item cloud-tool-share-btn" href="/rpost?attachment=[attachment]{{$item.resource}},{{$item.revision}}[/attachment]&acl[allow_cid]={{$item.raw_allow_cid}}&acl[allow_gid]={{$item.raw_allow_gid}}&acl[deny_cid]={{$item.raw_deny_cid}}&acl[deny_gid]={{$item.raw_deny_gid}}" data-id="{{$item.attach_id}}"><i class="fa fa-fw fa-share-square-o"></i> {{$post_label}}</a> {{/if}} - <a id="cloud-tool-download-btn-{{$item.attach_id}}" class="dropdown-item cloud-tool-download-btn" href="/attach/{{$item.resource}}" data-id="{{$item.attach_id}}"><i class="fa fa-fw fa-cloud-download"></i> {{$download_label}}</a> + <a download="{{$item.name}}" id="cloud-tool-download-btn-{{$item.attach_id}}" class="dropdown-item cloud-tool-download-btn" href="/attach/{{$item.resource}}" data-id="{{$item.attach_id}}"><i class="fa fa-fw fa-cloud-download"></i> {{$download_label}}</a> {{/if}} <a id="cloud-tool-delete-btn-{{$item.attach_id}}" class="dropdown-item cloud-tool-delete-btn" href="#" data-id="{{$item.attach_id}}"><i class="fa fa-fw fa-trash-o"></i> {{$delete_label}}</a> </div> diff --git a/view/tpl/connections.tpl b/view/tpl/connections.tpl index 5fec38a84..5fb6b0007 100644 --- a/view/tpl/connections.tpl +++ b/view/tpl/connections.tpl @@ -22,6 +22,7 @@ <form action="{{$cmd}}" method="get" name="contacts-search-form"> <div class="input-group mb-3"> <input type="text" name="search" id="contacts-search" class="form-control" onfocus="this.select();" value="{{$search}}" placeholder="{{$desc}}" /> + <input type="hidden" name="search_xchan" id="contacts-search-xchan" value=""/> <button id="contacts-search-submit" class="btn btn-primary" type="submit"><i class="fa fa-fw fa-search"></i></button> </div> </form> diff --git a/view/tpl/conv_item.tpl b/view/tpl/conv_item.tpl index 47261d070..3f760998d 100644 --- a/view/tpl/conv_item.tpl +++ b/view/tpl/conv_item.tpl @@ -26,14 +26,33 @@ <hr class="m-0"> {{/if}} {{/if}} - <div class="p-2 clearfix wall-item-head{{if !$item.title && !$item.event && !$item.photo}} rounded-top{{/if}}{{if $item.is_new && !$item.event && !$item.is_comment}} wall-item-head-new{{/if}}" > - {{if $item.thr_parent}} - <a href="javascript:doscroll('{{$item.thr_parent}}',{{$item.parent}});" title="{{$item.top_hint}}" class="float-end"><i class="fa fa-angle-double-up"> </i></a> - {{/if}} - {{if $item.pinned}} - <span class="float-end wall-item-pinned" title="{{$item.pinned}}" id="wall-item-pinned-{{$item.id}}"><i class="fa fa-thumb-tack"> </i></span> - {{/if}} - <div class="wall-item-info" id="wall-item-info-{{$item.id}}" > + <div class="p-2 wall-item-head{{if !$item.title && !$item.event && !$item.photo}} rounded-top{{/if}}{{if $item.is_new && !$item.event && !$item.is_comment}} wall-item-head-new{{/if}}" > + <div class="text-end float-end"> + <div class="wall-item-ago opacity-75" id="wall-item-ago-{{$item.id}}"> + {{if $item.editedtime}} + <i class="fa fa-pencil"></i> + {{/if}} + {{if $item.delayed}} + <i class="fa fa-clock-o"></i> + {{/if}} + {{if $item.location}} + <small class="wall-item-location p-location" id="wall-item-location-{{$item.id}}">{{$item.location}}</small> + {{/if}} + {{if $item.verified}} + <i class="fa fa-check text-success" title="{{$item.verified}}"></i> + {{elseif $item.forged}} + <i class="fa fa-exclamation text-danger" title="{{$item.forged}}"></i> + {{/if}} + <small class="autotime" title="{{$item.isotime}}"><time class="dt-published" datetime="{{$item.isotime}}">{{$item.localtime}}</time>{{if $item.editedtime}} {{$item.editedtime}}{{/if}}{{if $item.expiretime}} {{$item.expiretime}}{{/if}}</small> + </div> + {{if $item.thr_parent}} + <a href="javascript:doscroll('{{$item.thr_parent}}',{{$item.parent}});" class="ms-3" title="{{$item.top_hint}}"><i class="fa fa-angle-double-up"></i></a> + {{/if}} + {{if $item.pinned}} + <div class="wall-item-pinned" title="{{$item.pinned}}" id="wall-item-pinned-{{$item.id}}"><i class="fa fa-thumb-tack"></i></div> + {{/if}} + </div> + <div class="float-start wall-item-info pe-2" id="wall-item-info-{{$item.id}}" > <div class="wall-item-photo-wrapper{{if $item.owner_url}} wwfrom{{/if}} h-card p-author" id="wall-item-photo-wrapper-{{$item.id}}"> {{if $item.contact_id}} <div class="spinner-wrapper contact-edit-rotator contact-edit-rotator-{{$item.contact_id}}"><div class="spinner s"></div></div> @@ -52,18 +71,17 @@ {{/if}} </div> </div> - {{if $item.lock}} - <div class="wall-item-lock dropdown"> - <i class="fa {{if $item.locktype == 2}}fa-envelope-o{{else if $item.locktype == 1}}fa-lock{{else}}fa-unlock{{/if}} lockview{{if $item.privacy_warning}} text-danger{{/if}}" data-bs-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i> - <div id="panel-{{$item.id}}" class="dropdown-menu"></div> - </div> - {{/if}} <div class="wall-item-author"> - {{if $item.previewing}}<span class="preview-indicator"><i class="fa fa-eye" title="{{$item.preview_lbl}}"></i></span> {{/if}} - <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link u-url"><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" ><bdi>{{$item.name}}</bdi></span></a>{{if $item.owner_url}} {{$item.via}} <a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}"><bdi>{{$item.owner_name}}</bdi></span></a>{{/if}} - </div> - <div class="wall-item-ago" id="wall-item-ago-{{$item.id}}"> - {{if $item.verified}}<i class="fa fa-check item-verified" title="{{$item.verified}}"></i> {{elseif $item.forged}}<i class="fa fa-exclamation item-forged" title="{{$item.forged}}"></i> {{/if}}{{if $item.location}}<span class="wall-item-location p-location" id="wall-item-location-{{$item.id}}">{{$item.location}}, </span>{{/if}}<span class="autotime" title="{{$item.isotime}}"><time class="dt-published" datetime="{{$item.isotime}}">{{$item.localtime}}</time>{{if $item.editedtime}} {{$item.editedtime}}{{/if}}{{if $item.expiretime}} {{$item.expiretime}}{{/if}}</span> {{if $item.delayed}}<i class="fa fa-clock-o"></i>{{/if}}{{if $item.editedtime}} <i class="fa fa-pencil"></i>{{/if}} {{if $item.app}}<span class="item.app">{{$item.str_app}}</span>{{/if}} + {{if $item.lock}} + <div class="float-start dropdown wall-item-lock"> + <i class="fa {{if $item.locktype == 2}}fa-envelope-o{{else if $item.locktype == 1}}fa-lock{{else}}fa-unlock{{/if}} lockview{{if $item.privacy_warning}} text-danger{{/if}}" data-bs-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i> + <div id="panel-{{$item.id}}" class="dropdown-menu"></div> + </div> + {{/if}} + <div class="text-truncate"> + <a href="{{$item.profile_url}}" class="lh-sm wall-item-name-link u-url"{{if $item.app}} title="{{$item.str_app}}"{{/if}}><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" ><bdi>{{$item.name}}</bdi></span></a>{{if $item.owner_url}} {{$item.via}} <a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}"><bdi>{{$item.owner_name}}</bdi></span></a>{{/if}} + </div> + <small class="lh-sm text-truncate d-block wall-item-addr opacity-75">{{$item.author_id}}</small> </div> </div> {{if $item.divider}} diff --git a/view/tpl/conv_list.tpl b/view/tpl/conv_list.tpl index fde78e71e..0024ec382 100644 --- a/view/tpl/conv_list.tpl +++ b/view/tpl/conv_list.tpl @@ -26,13 +26,38 @@ <hr class="m-0"> {{/if}} {{/if}} - <div class="p-2 clearfix wall-item-head{{if !$item.title && !$item.event && !$item.photo}} rounded-top{{/if}}{{if $item.is_new && !$item.event && !$item.is_comment}} wall-item-head-new{{/if}}"> - <div class="wall-item-info" id="wall-item-info-{{$item.id}}" > + <div class="p-2 wall-item-head{{if !$item.title && !$item.event && !$item.photo}} rounded-top{{/if}}{{if $item.is_new && !$item.event && !$item.is_comment}} wall-item-head-new{{/if}}" > + <div class="text-end float-end"> + <div class="wall-item-ago opacity-75" id="wall-item-ago-{{$item.id}}"> + {{if $item.editedtime}} + <i class="fa fa-pencil"></i> + {{/if}} + {{if $item.delayed}} + <i class="fa fa-clock-o"></i> + {{/if}} + {{if $item.location}} + <small class="wall-item-location p-location" id="wall-item-location-{{$item.id}}">{{$item.location}}</small> + {{/if}} + {{if $item.verified}} + <i class="fa fa-check text-success" title="{{$item.verified}}"></i> + {{elseif $item.forged}} + <i class="fa fa-exclamation text-danger" title="{{$item.forged}}"></i> + {{/if}} + <small class="autotime" title="{{$item.isotime}}"><time class="dt-published" datetime="{{$item.isotime}}">{{$item.localtime}}</time>{{if $item.editedtime}} {{$item.editedtime}}{{/if}}{{if $item.expiretime}} {{$item.expiretime}}{{/if}}</small> + </div> + {{if $item.thr_parent}} + <a href="javascript:doscroll('{{$item.thr_parent}}',{{$item.parent}});" class="ms-3" title="{{$item.top_hint}}"><i class="fa fa-angle-double-up"></i></a> + {{/if}} + {{if $item.pinned}} + <div class="wall-item-pinned" title="{{$item.pinned}}" id="wall-item-pinned-{{$item.id}}"><i class="fa fa-thumb-tack"></i></div> + {{/if}} + </div> + <div class="float-start wall-item-info pe-2" id="wall-item-info-{{$item.id}}" > <div class="wall-item-photo-wrapper{{if $item.owner_url}} wwfrom{{/if}} h-card p-author" id="wall-item-photo-wrapper-{{$item.id}}"> {{if $item.contact_id}} <div class="spinner-wrapper contact-edit-rotator contact-edit-rotator-{{$item.contact_id}}"><div class="spinner s"></div></div> {{/if}} - <img src="{{$item.thumb}}" class="fakelink wall-item-photo{{$item.sparkle}} u-photo p-name" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" data-bs-toggle="dropdown" loading="lazy" /></a> + <img src="{{$item.thumb}}" class="fakelink wall-item-photo{{$item.sparkle}} u-photo p-name" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" loading="lazy" data-bs-toggle="dropdown" /> {{if $item.author_is_group_actor}} <i class="fa fa-comments-o wall-item-photo-group-actor" title="{{$item.author_is_group_actor}}"></i> {{/if}} @@ -40,27 +65,28 @@ <i class="fa fa-caret-down wall-item-photo-caret cursor-pointer" data-bs-toggle="dropdown"></i> <div class="dropdown-menu"> {{foreach $item.thread_author_menu as $mitem}} - <a class="dropdown-item" {{if $mitem.href}}href="{{$mitem.href}}"{{/if}} {{if $mitem.action}}onclick="{{$mitem.action}}"{{/if}} {{if $mitem.title}}title="{{$mitem.title}}"{{/if}} >{{$mitem.title}}</a> + <a class="dropdown-item{{if $mitem.class}} {{$mitem.class}}{{/if}}" {{if $mitem.href}}href="{{$mitem.href}}"{{/if}} {{if $mitem.action}}onclick="{{$mitem.action}}"{{/if}} {{if $mitem.title}}title="{{$mitem.title}}"{{/if}}{{if $mitem.data}} {{$mitem.data}}{{/if}}>{{$mitem.title}}</a> {{/foreach}} - </div> {{/if}} </div> </div> - {{if $item.lock}} - <div class="wall-item-lock dropdown"> - <i class="fa {{if $item.locktype == 2}}fa-envelope-o{{else if $item.locktype == 1}}fa-lock{{else}}fa-unlock{{/if}} lockview{{if $item.privacy_warning}} text-danger{{/if}}" data-bs-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i> - <div id="panel-{{$item.id}}" class="dropdown-menu"></div> - </div> - {{/if}} <div class="wall-item-author"> - <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link u-url"><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" ><bdi>{{$item.name}}</bdi></span></a>{{if $item.owner_url}} {{$item.via}} <a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}"><bdi>{{$item.owner_name}}</bdi></span></a>{{/if}} - </div> - <div class="wall-item-ago" id="wall-item-ago-{{$item.id}}"> - {{if $item.verified}}<i class="fa fa-check item-verified" title="{{$item.verified}}"></i> {{elseif $item.forged}}<i class="fa fa-exclamation item-forged" title="{{$item.forged}}"></i> {{/if}}{{if $item.location}}<span class="wall-item-location p-location" id="wall-item-location-{{$item.id}}">{{$item.location}}, </span>{{/if}}<span class="autotime" title="{{$item.isotime}}"><time class="dt-published" datetime="{{$item.isotime}}">{{$item.localtime}}</time>{{if $item.editedtime}} {{$item.editedtime}}{{/if}}{{if $item.expiretime}} {{$item.expiretime}}{{/if}}</span>{{if $item.editedtime}} <i class="fa fa-pencil"></i>{{/if}} {{if $item.app}}<span class="item.app">{{$item.str_app}}</span>{{/if}} + {{if $item.lock}} + <div class="float-start dropdown wall-item-lock"> + <i class="fa {{if $item.locktype == 2}}fa-envelope-o{{else if $item.locktype == 1}}fa-lock{{else}}fa-unlock{{/if}} lockview{{if $item.privacy_warning}} text-danger{{/if}}" data-bs-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i> + <div id="panel-{{$item.id}}" class="dropdown-menu"></div> + </div> + {{/if}} + <div class="text-truncate"> + <a href="{{$item.profile_url}}" class="lh-sm wall-item-name-link u-url"{{if $item.app}} title="{{$item.str_app}}"{{/if}}><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" ><bdi>{{$item.name}}</bdi></span></a>{{if $item.owner_url}} {{$item.via}} <a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}"><bdi>{{$item.owner_name}}</bdi></span></a>{{/if}} + </div> + <small class="lh-sm text-truncate d-block wall-item-addr opacity-75">{{$item.author_id}}</small> </div> </div> - + {{if $item.divider}} + <hr class="wall-item-divider"> + {{/if}} {{if $item.body}} <div class="p-2 wall-item-content clearfix" id="wall-item-content-{{$item.id}}"> <div class="wall-item-body e-content" id="wall-item-body-{{$item.id}}" > diff --git a/view/tpl/messages_widget.tpl b/view/tpl/messages_widget.tpl index ee933b392..5770abffc 100644 --- a/view/tpl/messages_widget.tpl +++ b/view/tpl/messages_widget.tpl @@ -25,34 +25,55 @@ <div id="messages-widget" class="border-start border-end border-bottom overflow-auto mb-3 clearfix" style="height: 70vh;"> <div id="messages-template" rel="template" class="d-none"> <a href="{6}" class="list-group-item list-group-item-action message" data-b64mid="{0}"> - <div class="d-flex w-100 justify-content-between"> - <div class="mb-1 text-truncate" title="{5}"> - {7} - <strong>{4}</strong> + <div class="mb-2"> + <img src="{9}" loading="lazy" class="rounded menu-img-2"> + <div class="text-nowrap"> + <div class="d-flex justify-content-between align-items-center lh-sm"> + <div class="text-truncate pe-1"> + {7} + <strong title="{4}">{4}</strong> + </div> + <small class="messages-timeago opacity-75" title="{1}"></small> + </div> + <div class="text-truncate"> + <small class="opacity-75" title="{5}">{5}</small> + </div> </div> - <small class="messages-timeago text-nowrap" title="{1}"></small> </div> - <div class="mb-1"> + <div class="mb-2"> <div class="text-break">{2}</div> </div> - <small>{3}</small> + <small class="opacity-75">{3}</small> {8} </a> </div> - <div id="dm-container" class="list-group list-group-flush" data-offset="10"> + <div id="messages-container" class="list-group list-group-flush" data-offset="10"> + <div id="messages-author-container" class="list-group-item notifications-textinput"> + <div class="text-muted notifications-textinput-filter"><i class="fa fa-fw fa-filter"></i></div> + <input id="messages-author" type="text" class="form-control form-control-sm" placeholder="{{$strings.filter}}"> + <div id="messages-author-input-clear" class="text-muted notifications-textinput-clear d-none"><i class="fa fa-times"></i></div> + </div> {{foreach $entries as $e}} <a href="{{$e.href}}" class="list-group-item list-group-item-action message" data-b64mid="{{$e.b64mid}}"> - <div class="d-flex w-100 justify-content-between"> - <div class="mb-1 text-truncate" title="{{$e.author_addr}}"> - {{$e.icon}} - <strong>{{$e.author_name}}</strong> + <div class="mb-2"> + <img src="{{$e.author_img}}" loading="lazy" class="rounded menu-img-2"> + <div class="text-nowrap"> + <div class="d-flex justify-content-between align-items-center lh-sm"> + <div class="text-truncate pe-1"> + {{$e.icon}} + <strong title="{{$e.author_name}}">{{$e.author_name}}</strong> + </div> + <small class="messages-timeago opacity-75" title="{{$e.created}}"></small> + </div> + <div class="text-truncate"> + <small class="opacity-75" title="{{$e.author_addr}}">{{$e.author_addr}}</small> + </div> </div> - <small class="messages-timeago text-nowrap" title="{{$e.created}}"></small> </div> - <div class="mb-1"> + <div class="mb-2"> <div class="text-break">{{$e.summary}}</div> </div> - <small>{{$e.info}}</small> + <small class="opacity-75">{{$e.info}}</small> {{if $e.unseen_count}} <span class="badge bg-transparent border border-{{$e.unseen_class}} text-{{$e.unseen_class}} rounded-pill position-absolute bottom-0 end-0 m-2" title="{{$strings.unseen_count}}">{{$e.unseen_count}}</span> {{/if}} @@ -67,15 +88,48 @@ </div> </div> <script> - var messages_offset = {{$offset}}; - var get_messages_page_active = false; - var messages_type; + let messages_offset = {{$offset}}; + let get_messages_page_active = false; + let messages_type; + let author_hash; + let author_url; + let author; $(document).ready(function () { $('.messages-timeago').timeago(); if (bParam_mid) { $('.message[data-b64mid=\'' + bParam_mid + '\']').addClass('active'); } + + $("#messages-author").name_autocomplete(baseurl + '/acl', 'a', false, function(data) { + // a workaround to not re-trigger autocomplete after initial click + $("#messages-author").val('').attr('placeholder', data.name); + $('#textcomplete-dropdown').hide(); + + $('#messages-container .message').remove(); + $('#messages-author-container').addClass('active sticky-top'); + $('#messages-author-input-clear').removeClass('d-none'); + author_hash = data.xid; + author_url = data.url; + author = messages_type === 'notification' ? author_url : author_hash; + messages_offset = 0; + get_messages_page(); + }); + + $(document).on('click', '#messages-author-input-clear', function() { + $('#messages-author').val(''); + $("#messages-author").attr('placeholder', '{{$strings.filter}}'); + + $('#messages-author-container').removeClass('active sticky-top'); + $('#messages-author-input-clear').addClass('d-none'); + $('#messages-container .message').remove(); + author = ''; + author_hash = ''; + author_url = ''; + messages_offset = 0; + get_messages_page(); + }); + }); $('#messages-widget').on('scroll', function() { @@ -90,7 +144,8 @@ $(this).addClass('active'); messages_offset = 0; messages_type = $(this).data('messages_type'); - $('#dm-container .message').remove(); + author = messages_type === 'notification' ? author_url : author_hash; + $('#messages-container .message').remove(); get_messages_page(); }); @@ -111,7 +166,8 @@ url: 'hq', data: { offset: messages_offset, - type: messages_type + type: messages_type, + author: author } }).done(function(obj) { get_messages_page_active = false; @@ -129,7 +185,8 @@ e.author_addr, e.href, e.icon, - e.unseen_count ? '<span class="badge bg-transparent border border-' + e.unseen_class + ' text-' + e.unseen_class + ' rounded-pill position-absolute bottom-0 end-0 m-2" title="{{$strings.unseen_count}}">' + e.unseen_count + '</span>' : '' + e.unseen_count ? '<span class="badge bg-transparent border border-' + e.unseen_class + ' text-' + e.unseen_class + ' rounded-pill position-absolute bottom-0 end-0 m-2" title="{{$strings.unseen_count}}">' + e.unseen_count + '</span>' : '', + e.author_img ); $('#messages-loading').before(html); }); @@ -144,5 +201,6 @@ $('.messages-timeago').timeago(); }); + } </script> diff --git a/view/tpl/navbar_default.tpl b/view/tpl/navbar_default.tpl index 4861c196f..ca61bcb8e 100644 --- a/view/tpl/navbar_default.tpl +++ b/view/tpl/navbar_default.tpl @@ -1,14 +1,14 @@ -<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark"> +<nav class="navbar fixed-top navbar-expand-lg bg-body-tertiary" {{$navbar_color_mode}}> <div class="container-fluid flex-nowrap"> {{if $userinfo}} <div class="d-flex" style="max-width: 50%"> <div class="dropdown"> - <div class="fakelink usermenu" data-bs-toggle="dropdown"> + <div class="cursor-pointer usermenu" data-bs-toggle="dropdown"> <img id="avatar" src="{{$userinfo.icon}}" alt="{{$userinfo.name}}"> - <i class="fa fa-caret-down"></i> + <i class="navbar-text fa fa-caret-down"></i> </div> {{if $is_owner}} - <div class="dropdown-menu"> + <div class="dropdown-menu" {{$color_mode}}> {{foreach $nav.usermenu as $usermenu}} <a class="dropdown-item{{if $usermenu.2}} active{{/if}}" href="{{$usermenu.0}}" title="{{$usermenu.3}}" role="menuitem" id="{{$usermenu.4}}">{{$usermenu.1}}</a> {{/foreach}} @@ -41,7 +41,7 @@ </div> {{/if}} {{if ! $is_owner}} - <div class="dropdown-menu" role="menu" aria-labelledby="avatar"> + <div class="dropdown-menu" role="menu" aria-labelledby="avatar" {{$color_mode}}> <a class="dropdown-item" href="{{$nav.rusermenu.0}}" role="menuitem">{{$nav.rusermenu.1}}</a> <a class="dropdown-item" href="{{$nav.rusermenu.2}}" role="menuitem">{{$nav.rusermenu.3}}</a> </div> @@ -66,7 +66,7 @@ {{/if}} </div> {{else}} - <div id="banner" class="navbar-text d-lg-none">{{$banner}}</div> + <div class="navbar-text d-lg-none navbar-banner">{{$banner}}</div> {{/if}} <div class="navbar-toggler-right"> {{if $nav.help.6}} @@ -91,7 +91,7 @@ {{if $nav.login && !$userinfo}} <li class="nav-item d-lg-flex"> {{if $nav.loginmenu.1.4}} - <a class="nav-link" href="#" title="{{$nav.loginmenu.1.3}}" id="{{$nav.loginmenu.1.4}}" data-bs-toggle="modal" data-bs-target="#nav-login"> + <a class="nav-link" href="#" title="{{$nav.loginmenu.1.3}}" data-bs-toggle="modal" data-bs-target="#nav-login"> {{$nav.loginmenu.1.1}} </a> {{else}} @@ -103,7 +103,7 @@ {{/if}} {{if $nav.register}} <li class="nav-item {{$nav.register.2}} d-lg-flex"> - <a class="nav-link" href="{{$nav.register.0}}" title="{{$nav.register.3}}" id="{{$nav.register.4}}">{{$nav.register.1}}</a> + <a class="nav-link" href="{{$nav.register.0}}" title="{{$nav.register.3}}">{{$nav.register.1}}</a> </li> {{/if}} {{if $nav.alogout}} @@ -113,10 +113,10 @@ {{/if}} </ul> - <div id="banner" class="navbar-text">{{$banner}}</div> + <div class="navbar-text navbar-banner">{{$banner}}</div> <ul id="nav-right" class="navbar-nav"> - <li class="nav-item collapse clearfix" id="nav-search"> + <li class="nav-item collapse clearfix" id="nav-search" {{$color_mode}}> <form class="form-inline" method="get" action="{{$nav.search.4}}" role="search"> <input class="form-control form-control-sm mt-1 me-2" id="nav-search-text" type="text" value="" placeholder="{{$help}}" name="search" title="{{$nav.search.3}}" onclick="this.submit();" onblur="closeMenu('nav-search'); openMenu('nav-search-btn');"/> </form> @@ -134,7 +134,7 @@ {{/if}} {{if $localuser || $nav.pubs}} <li id="notifications-btn" class="nav-item d-xl-none"> - <a class="nav-link text-white notifications-btn" href="#"><i id="notifications-btn-icon" class="fa fa-exclamation-circle notifications-btn-icon"></i></a> + <a class="nav-link notifications-btn" href="#"><i id="notifications-btn-icon" class="fa fa-exclamation-circle notifications-btn-icon"></i></a> </li> {{/if}} {{if $navbar_apps}} @@ -162,10 +162,11 @@ </nav> <div class="offcanvas offcanvas-end" tabindex="-1" id="app-bin" aria-labelledby="app-bin-label"> <div class="offcanvas-header"> + {{if $nav.login && !$userinfo}} - <div class="d-lg-none pt-1 pb-1"> + <div class="hstack gap-1 d-lg-none pt-1 pb-1"> {{if $nav.loginmenu.1.4}} - <a class="btn btn-primary btn-sm text-white" href="#" title="{{$nav.loginmenu.1.3}}" id="{{$nav.loginmenu.1.4}}_collapse" data-bs-toggle="modal" data-bs-target="#nav-login"> + <a class="btn btn-primary btn-sm text-white" href="#" title="{{$nav.loginmenu.1.3}}" data-bs-toggle="modal" data-bs-target="#nav-login"> {{$nav.loginmenu.1.1}} </a> {{else}} @@ -174,12 +175,13 @@ </a> {{/if}} {{if $nav.register}} - <a class="btn btn-warning btn-sm text-dark" href="{{$nav.register.0}}" title="{{$nav.register.3}}" id="{{$nav.register.4}}" > + <a class="btn btn-warning btn-sm text-dark" href="{{$nav.register.0}}" title="{{$nav.register.3}}"> {{$nav.register.1}} </a> {{/if}} + </div> - <div class="nav d-lg-flex"></div> + <div class="nav d-lg-flex w-100"></div> {{else}} <div class="lh-sm w-100" id="app-bin-label"> {{if $name}} @@ -192,8 +194,10 @@ </div> <i id="app-bin-trash" class="fa fa-2x fa-fw fa-trash-o d-none"></i> {{/if}} - - <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button> + <div class="hstack gap-1"> + <button id="theme-switch" type="button" class="btn btn-outline-secondary border-0"><i id="theme-switch-icon" class="fa fa-{{$theme_switch_icon}}-o"></i></button> + <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button> + </div> </div> <div class="offcanvas-body"> diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl index 7a4e909c7..bae1c1469 100644 --- a/view/tpl/notifications_widget.tpl +++ b/view/tpl/notifications_widget.tpl @@ -357,10 +357,10 @@ function sse_handleNotificationsItems(notifyType, data, replace, followup) { - var notifications_tpl = ((notifyType == 'forums') ? decodeURIComponent($("#nav-notifications-forums-template[rel=template]").html().replace('data-src', 'src')) : decodeURIComponent($("#nav-notifications-template[rel=template]").html().replace('data-src', 'src'))); - var notify_menu = $("#nav-" + notifyType + "-menu"); - var notify_loading = $("#nav-" + notifyType + "-loading"); - var notify_count = $("." + notifyType + "-update"); + let notifications_tpl = ((notifyType == 'forums') ? decodeURIComponent($("#nav-notifications-forums-template[rel=template]").html().replace('data-src', 'src')) : decodeURIComponent($("#nav-notifications-template[rel=template]").html().replace('data-src', 'src'))); + let notify_menu = $("#nav-" + notifyType + "-menu"); + let notify_loading = $("#nav-" + notifyType + "-loading"); + let notify_count = $("." + notifyType + "-update"); if(replace && !followup) { notify_menu.html(''); @@ -370,14 +370,17 @@ $(data).each(function() { // do not add a notification if it is already present - if($('#nav-' + notifyType + '-menu .notification[data-b64mid=\'' + this.b64mid + '\']').length) - return true; + + // TODO: this is questionable because at least in 'notify' notification type an item can have more than one notifications + // e.g. one for the mention and one for the item itself. + //if($('#nav-' + notifyType + '-menu .notification[data-b64mid=\'' + this.b64mid + '\']').length) + // return true; if(!replace && !followup && (this.thread_top && notifyType === 'network')) { $(document).trigger('hz:handleNetworkNotificationsItems', this); } - html = notifications_tpl.format(this.notify_link,this.photo,this.name,this.addr,this.message,this.when,this.hclass,this.b64mid,this.notify_id,this.thread_top,this.unseen,this.private_forum, encodeURIComponent(this.mids), this.body); + let html = notifications_tpl.format(this.notify_link,this.photo,this.name,this.addr,this.message,this.when,this.hclass,this.b64mid,this.notify_id,this.thread_top,this.unseen,this.private_forum, encodeURIComponent(this.mids), this.body); notify_menu.append(html); }); @@ -395,13 +398,13 @@ $('#nav-' + notifyType + '-menu [data-thread_top=false]').addClass('tt-filter-active'); if($('#cn-' + notifyType + '-input').length) { - var filter = $('#cn-' + notifyType + '-input').val().toString().toLowerCase(); + let filter = $('#cn-' + notifyType + '-input').val().toString().toLowerCase(); if(filter) { filter = filter.indexOf('%') == 0 ? filter.substring(1) : filter; $('#nav-' + notifyType + '-menu .notification').each(function(i, el) { - var cn = $(el).data('contact_name').toString().toLowerCase(); - var ca = $(el).data('contact_addr').toString().toLowerCase(); + let cn = $(el).data('contact_name').toString().toLowerCase(); + let ca = $(el).data('contact_addr').toString().toLowerCase(); if(cn.indexOf(filter) === -1 && ca.indexOf(filter) === -1) $(el).addClass('cn-filter-active'); else @@ -531,43 +534,53 @@ {{$no_notifications}}<span class="jumping-dots"><span class="dot-1">.</span><span class="dot-2">.</span><span class="dot-3">.</span></span> </div> <div id="nav-notifications-template" rel="template"> - <a class="list-group-item text-decoration-none text-dark clearfix notification {6}" href="{0}" title="{13}" data-b64mid="{7}" data-notify_id="{8}" data-thread_top="{9}" data-contact_name="{2}" data-contact_addr="{3}" data-when="{5}"> - <img class="menu-img-3" data-src="{1}" loading="lazy"> - <div class="contactname"><span class="text-dark fw-bold">{2}</span> <span class="text-muted">{3}</span></div> - <span class="text-muted">{4}</span><br> - <span class="text-muted notifications-autotime" title="{5}">{5}</span> + <a class="list-group-item list-group-item-action notification {6}" href="{0}" title="{13}" data-b64mid="{7}" data-notify_id="{8}" data-thread_top="{9}" data-contact_name="{2}" data-contact_addr="{3}" data-when="{5}"> + <img data-src="{1}" loading="lazy" class="rounded menu-img-2"> + <div class="text-nowrap"> + <div class="d-flex justify-content-between align-items-center lh-sm"> + <div class="text-truncate pe-1"> + <strong title="{2} - {3}">{2}</strong> + </div> + <small class="notifications-autotime opacity-75" title="{5}"></small> + </div> + <div class="text-truncate">{4}</div> + </div> </a> </div> <div id="nav-notifications-forums-template" rel="template"> - <a class="list-group-item text-decoration-none clearfix notification notification-forum" href="{0}" title="{4} - {3}" data-b64mid="{7}" data-notify_id="{8}" data-thread_top="{9}" data-contact_name="{2}" data-contact_addr="{3}" data-b64mids='{12}'> - <span class="float-end badge bg-secondary">{10}</span> - <img class="menu-img-1" data-src="{1}" loading="lazy"> - <span class="">{2}</span> - <i class="fa fa-{11} text-muted"></i> + <a class="list-group-item list-group-item-action justify-content-between align-items-center d-flex notification notification-forum" href="{0}" title="{4} - {3}" data-b64mid="{7}" data-notify_id="{8}" data-thread_top="{9}" data-contact_name="{2}" data-contact_addr="{3}" data-b64mids='{12}'> + <div> + <img class="menu-img-1" data-src="{1}" loading="lazy"> + <span>{2}</span> + </div> + <span class="badge bg-secondary">{10}</span> </a> </div> <div id="notifications" class="border border-top-0 rounded navbar-nav collapse"> {{foreach $notifications as $notification}} <div class="rounded-top rounded-bottom border border-start-0 border-end-0 border-bottom-0 list-group list-group-flush collapse {{$notification.type}}-button"> - <a id="notification-link-{{$notification.type}}" class="collapsed list-group-item fakelink notification-link" href="#" title="{{$notification.title}}" data-bs-target="#nav-{{$notification.type}}-sub" data-bs-toggle="collapse" data-sse_type="{{$notification.type}}"> - <i class="fa fa-fw fa-{{$notification.icon}}"></i> {{$notification.label}} - <span class="float-end badge bg-{{$notification.severity}} {{$notification.type}}-update"></span> + <a id="notification-link-{{$notification.type}}" class="collapsed list-group-item justify-content-between align-items-center d-flex fakelink stretched-link notification-link" href="#" title="{{$notification.title}}" data-bs-target="#nav-{{$notification.type}}-sub" data-bs-toggle="collapse" data-sse_type="{{$notification.type}}"> + <div> + <i class="fa fa-fw fa-{{$notification.icon}}"></i> + {{$notification.label}} + </div> + <span class="badge bg-{{$notification.severity}} {{$notification.type}}-update"></span> </a> </div> <div id="nav-{{$notification.type}}-sub" class="rounded-bottom border border-start-0 border-end-0 border-bottom-0 list-group list-group-flush collapse notification-content" data-bs-parent="#notifications" data-sse_type="{{$notification.type}}"> {{if $notification.viewall}} - <a class="list-group-item text-decoration-none text-dark" id="nav-{{$notification.type}}-see-all" href="{{$notification.viewall.url}}"> + <a class="list-group-item list-group-item-action text-decoration-none" id="nav-{{$notification.type}}-see-all" href="{{$notification.viewall.url}}"> <i class="fa fa-fw fa-external-link"></i> {{$notification.viewall.label}} </a> {{/if}} {{if $notification.markall}} - <div class="list-group-item cursor-pointer" id="nav-{{$notification.type}}-mark-all" onclick="markRead('{{$notification.type}}'); return false;"> + <div class="list-group-item list-group-item-action cursor-pointer" id="nav-{{$notification.type}}-mark-all" onclick="markRead('{{$notification.type}}'); return false;"> <i class="fa fa-fw fa-check"></i> {{$notification.markall.label}} </div> {{/if}} {{if $notification.filter}} {{if $notification.filter.posts_label}} - <div class="list-group-item cursor-pointer" id="tt-{{$notification.type}}-only"> + <div class="list-group-item list-group-item-action cursor-pointer" id="tt-{{$notification.type}}-only"> <i class="fa fa-fw fa-filter"></i> {{$notification.filter.posts_label}} </div> {{/if}} diff --git a/view/tpl/pinned_item.tpl b/view/tpl/pinned_item.tpl index 4d059e0a4..ece386b72 100644 --- a/view/tpl/pinned_item.tpl +++ b/view/tpl/pinned_item.tpl @@ -1,15 +1,4 @@ -{{if $hide}} -<script> - function dopinhide(id) { - id = id.toString(); - if($('#pinned-wrapper-' + id).length) { - $('#pinned-wrapper-' + id).fadeTo('fast', 0.33, function() { this.remove(); }); - $.post('pin/hide', { 'id' : id }); - } - } -</script> -{{/if}} -<div id="pinned-wrapper-{{$id}}" class="pinned-item thread-wrapper toplevel_item generic-content-wrapper h-entry" data-b64mids='{{$mids}}'> +<div id="pinned-wrapper-{{$id}}" class="pinned-item toplevel_item generic-content-wrapper h-entry" data-b64mids='{{$mids}}'> <div class="wall-item-outside-wrapper" id="pinned-item-outside-wrapper-{{$id}}"> <div class="clearfix wall-item-content-wrapper" id="pinned-item-content-wrapper-{{$id}}"> {{if $photo}} @@ -40,26 +29,43 @@ <hr class="m-0"> {{/if}} {{/if}} - <div class="p-2 clearfix wall-item-head{{if !$title && !$event && !$photo}} rounded-top{{/if}}{{if $is_new && !$event}} wall-item-head-new{{/if}}"> - <span class="float-end" title="{{$pinned}}"><i class="fa fa-thumb-tack"> </i></span> - <div class="wall-item-info" id="pinned-item-info-{{$id}}" > - <div class="wall-item-photo-wrapper{{if $owner_url}} wwfrom{{/if}} h-card p-author" id="pinned-item-photo-wrapper-{{$id}}"> - <img src="{{$thumb}}" class="fakelink wall-item-photo u-photo p-name" id="pinned-item-photo-{{$id}}" alt="{{$name}}" data-bs-toggle="dropdown" /> + <div class="p-2 lh-sm d-flex wall-item-head{{if !$title && !$event && !$photo}} rounded-top{{/if}}{{if $is_new && !$event}} wall-item-head-new{{/if}}" > + <div class="wall-item-info pe-2" id="wall-item-info-{{$id}}" > + <div class="wall-item-photo-wrapper{{if $owner_url}} wwfrom{{/if}} h-card p-author" id="wall-item-photo-wrapper-{{$id}}"> + <img src="{{$thumb}}" class="fakelink wall-item-photo{{$sparkle}} u-photo p-name" id="wall-item-photo-{{$id}}" alt="{{$name}}" loading="lazy" data-bs-toggle="dropdown" /> {{if $thread_author_menu}} - <i class="fa fa-caret-down wall-item-photo-caret cursor-pointer" data-bs-toggle="dropdown"></i> - <div class="dropdown-menu"> - {{foreach $thread_author_menu as $mitem}} - <a class="dropdown-item" {{if $mitem.href}}href="{{$mitem.href}}"{{/if}} {{if $mitem.action}}onclick="{{$mitem.action}}"{{/if}} {{if $mitem.title}}title="{{$mitem.title}}"{{/if}} >{{$mitem.title}}</a> - {{/foreach}} - </div> + <i class="fa fa-caret-down wall-item-photo-caret cursor-pointer" data-bs-toggle="dropdown"></i> + <div class="dropdown-menu"> + {{foreach $thread_author_menu as $mitem}} + <a class="dropdown-item{{if $mitem.class}} {{$mitem.class}}{{/if}}" {{if $mitem.href}}href="{{$mitem.href}}"{{/if}} {{if $mitem.action}}onclick="{{$mitem.action}}"{{/if}} {{if $mitem.title}}title="{{$mitem.title}}"{{/if}}{{if $mitem.data}} {{$mitem.data}}{{/if}}>{{$mitem.title}}</a> + {{/foreach}} + </div> {{/if}} </div> </div> - <div class="wall-item-author"> - <a href="{{$profile_url}}" title="{{$linktitle}}" class="wall-item-name-link u-url"><span class="wall-item-name" id="pinned-item-name-{{$id}}" >{{$name}}</span></a>{{if $owner_url}} {{$via}} <a href="{{$owner_url}}" title="{{$olinktitle}}" class="wall-item-name-link"><span class="wall-item-name" id="pinned-item-ownername-{{$id}}">{{$owner_name}}</span></a>{{/if}} + <div class="wall-item-author text-truncate"> + <a href="{{$profile_url}}" title="{{$linktitle}}" class="wall-item-name-link u-url"><span class="wall-item-name" id="pinned-item-name-{{$id}}" >{{$name}}</span></a>{{if $owner_url}} {{$via}} <a href="{{$owner_url}}" title="{{$olinktitle}}" class="wall-item-name-link"><span class="wall-item-name" id="pinned-item-ownername-{{$id}}">{{$owner_name}}</span></a>{{/if}}<br> + <small class="wall-item-addr opacity-75">{{$author_id}}</small> </div> - <div class="wall-item-ago" id="pinned-item-ago-{{$id}}"> - {{if $verified}}<i class="fa fa-check item-verified" title="{{$verified}}"></i> {{elseif $forged}}<i class="fa fa-exclamation item-forged" title="{{$forged}}"></i> {{/if}}{{if $location}}<span class="wall-item-location p-location" id="pinned-item-location-{{$id}}">{{$location}}, </span>{{/if}}<span class="autotime" title="{{$isotime}}"><time class="dt-published" datetime="{{$isotime}}">{{$localtime}}</time>{{if $editedtime}} {{$editedtime}}{{/if}}{{if $expiretime}} {{$expiretime}}{{/if}}</span>{{if $editedtime}} <i class="fa fa-pencil"></i>{{/if}} {{if $app}}<span class="item.app">{{$str_app}}</span>{{/if}} + <div class="text-end ms-auto"> + <div class="wall-item-ago text-nowrap opacity-75" id="wall-item-ago-{{$id}}"> + {{if $editedtime}} + <i class="fa fa-pencil"></i> + {{/if}} + {{if $delayed}} + <i class="fa fa-clock-o"></i> + {{/if}} + {{if $location}} + <small class="wall-item-location p-location" id="wall-item-location-{{$id}}">{{$location}}</small> + {{/if}} + {{if $verified}} + <i class="fa fa-check text-success" title="{{$verified}}"></i> + {{elseif $forged}} + <i class="fa fa-exclamation text-danger" title="{{$forged}}"></i> + {{/if}} + <small class="autotime" title="{{$isotime}}"><time class="dt-published" datetime="{{$isotime}}">{{$localtime}}</time>{{if $editedtime}} {{$editedtime}}{{/if}}{{if $expiretime}} {{$expiretime}}{{/if}}</small> + </div> + <div class="wall-item-pinned" title="{{$pinned}}" id="wall-item-pinned-{{$id}}"><i class="fa fa-thumb-tack"></i></div> </div> </div> {{if $divider}} @@ -196,3 +202,17 @@ </div> </div> </div> +{{if $hide}} +<script> + function dopinhide(id) { + id = id.toString(); + if($('#pinned-wrapper-' + id).length) { + $('#pinned-wrapper-' + id).fadeTo('fast', 0.33, function() { this.remove(); }); + $.post('pin/hide', { 'id' : id }); + } + } +</script> +{{/if}} +<script> + $(".pinned-item .autotime").timeago(); +</script> diff --git a/view/tpl/search_item.tpl b/view/tpl/search_item.tpl index 7b63d83b8..b2a99b64a 100644 --- a/view/tpl/search_item.tpl +++ b/view/tpl/search_item.tpl @@ -20,13 +20,38 @@ <hr class="m-0"> {{/if}} {{/if}} - <div class="p-2 clearfix wall-item-head{{if !$item.title && !$item.event && !$item.photo}} rounded-top{{/if}}{{if $item.is_new && !$item.event && !$item.is_comment}} wall-item-head-new{{/if}}" > - <div class="wall-item-info" id="wall-item-info-{{$item.id}}" > - <div class="wall-item-photo-wrapper{{if $item.owner_url}} wwfrom{{/if}}" id="wall-item-photo-wrapper-{{$item.id}}"> + <div class="p-2 wall-item-head{{if !$item.title && !$item.event && !$item.photo}} rounded-top{{/if}}{{if $item.is_new && !$item.event && !$item.is_comment}} wall-item-head-new{{/if}}" > + <div class="text-end float-end"> + <div class="wall-item-ago opacity-75" id="wall-item-ago-{{$item.id}}"> + {{if $item.editedtime}} + <i class="fa fa-pencil"></i> + {{/if}} + {{if $item.delayed}} + <i class="fa fa-clock-o"></i> + {{/if}} + {{if $item.location}} + <small class="wall-item-location p-location" id="wall-item-location-{{$item.id}}">{{$item.location}}</small> + {{/if}} + {{if $item.verified}} + <i class="fa fa-check text-success" title="{{$item.verified}}"></i> + {{elseif $item.forged}} + <i class="fa fa-exclamation text-danger" title="{{$item.forged}}"></i> + {{/if}} + <small class="autotime" title="{{$item.isotime}}"><time class="dt-published" datetime="{{$item.isotime}}">{{$item.localtime}}</time>{{if $item.editedtime}} {{$item.editedtime}}{{/if}}{{if $item.expiretime}} {{$item.expiretime}}{{/if}}</small> + </div> + {{if $item.thr_parent}} + <a href="javascript:doscroll('{{$item.thr_parent}}',{{$item.parent}});" class="ms-3" title="{{$item.top_hint}}"><i class="fa fa-angle-double-up"></i></a> + {{/if}} + {{if $item.pinned}} + <div class="wall-item-pinned" title="{{$item.pinned}}" id="wall-item-pinned-{{$item.id}}"><i class="fa fa-thumb-tack"></i></div> + {{/if}} + </div> + <div class="float-start wall-item-info pe-2" id="wall-item-info-{{$item.id}}" > + <div class="wall-item-photo-wrapper{{if $item.owner_url}} wwfrom{{/if}} h-card p-author" id="wall-item-photo-wrapper-{{$item.id}}"> {{if $item.contact_id}} <div class="spinner-wrapper contact-edit-rotator contact-edit-rotator-{{$item.contact_id}}"><div class="spinner s"></div></div> {{/if}} - <img src="{{$item.thumb}}" class="fakelink wall-item-photo{{$item.sparkle}} u-photo p-name" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" data-bs-toggle="dropdown" loading="lazy" /> + <img src="{{$item.thumb}}" class="fakelink wall-item-photo{{$item.sparkle}} u-photo p-name" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" loading="lazy" data-bs-toggle="dropdown" /> {{if $item.author_is_group_actor}} <i class="fa fa-comments-o wall-item-photo-group-actor" title="{{$item.author_is_group_actor}}"></i> {{/if}} @@ -40,17 +65,22 @@ {{/if}} </div> </div> - {{if $item.lock}} - <div class="wall-item-lock dropdown"> - <i class="fa {{if $item.locktype == 2}}fa-envelope-o{{else if $item.locktype == 1}}fa-lock{{else}}fa-unlock{{/if}} lockview{{if $item.privacy_warning}} text-danger{{/if}}" data-bs-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i> - </div> - {{/if}} <div class="wall-item-author"> - {{if $item.previewing}}<span class="preview-indicator"><i class="fa fa-eye" title="{{$item.preview_lbl}}"></i></span> {{/if}} - <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" ><bdi>{{$item.name}}</bdi></span></a>{{if $item.owner_url}} {{$item.via}} <a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}"><bdi>{{$item.owner_name}}</bdi></span></a>{{/if}} - </div> - <div class="wall-item-ago" id="wall-item-ago-{{$item.id}}"> - {{if $item.verified}}<i class="fa fa-check item-verified" title="{{$item.verified}}"></i> {{elseif $item.forged}}<i class="fa fa-exclamation item-forged" title="{{$item.forged}}"></i> {{/if}}{{if $item.location}}<span class="wall-item-location" id="wall-item-location-{{$item.id}}">{{$item.location}}, </span>{{/if}}<span class="autotime" title="{{$item.isotime}}">{{$item.localtime}}{{if $item.editedtime}} {{$item.editedtime}}{{/if}}{{if $item.expiretime}} {{$item.expiretime}}{{/if}}</span>{{if $item.editedtime}} <i class="fa fa-pencil"></i>{{/if}} {{if $item.app}}<span class="item.app">{{$item.str_app}}</span>{{/if}} + {{if $item.previewing}} + <div class="float-start me-1 preview-indicator"> + <i class="fa fa-eye" title="{{$item.preview_lbl}}"></i> + </div> + {{/if}} + {{if $item.lock}} + <div class="float-start dropdown wall-item-lock"> + <i class="fa {{if $item.locktype == 2}}fa-envelope-o{{else if $item.locktype == 1}}fa-lock{{else}}fa-unlock{{/if}} lockview{{if $item.privacy_warning}} text-danger{{/if}}" data-bs-toggle="dropdown" title="{{$item.lock}}" onclick="lockview('item',{{$item.id}});" ></i> + <div id="panel-{{$item.id}}" class="dropdown-menu"></div> + </div> + {{/if}} + <div class="text-truncate"> + <a href="{{$item.profile_url}}" class="lh-sm wall-item-name-link u-url"{{if $item.app}} title="{{$item.str_app}}"{{/if}}><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" ><bdi>{{$item.name}}</bdi></span></a>{{if $item.owner_url}} {{$item.via}} <a href="{{$item.owner_url}}" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}"><bdi>{{$item.owner_name}}</bdi></span></a>{{/if}} + </div> + <small class="lh-sm text-truncate d-block wall-item-addr opacity-75">{{$item.author_id}}</small> </div> </div> {{if $item.divider}} diff --git a/view/tpl/settings_account.tpl b/view/tpl/settings_account.tpl index 2b942d694..0280b2962 100644 --- a/view/tpl/settings_account.tpl +++ b/view/tpl/settings_account.tpl @@ -17,6 +17,7 @@ <div class="settings-submit-wrapper" > <button type="submit" name="submit" class="btn btn-primary">{{$submit}}</button> + <a href="/settings/multifactor" class="btn btn-outline-success">{{$mfa}}</a> </div> {{$account_settings}} </div> diff --git a/view/tpl/totp.tpl b/view/tpl/totp.tpl new file mode 100644 index 000000000..1f3b1cfc7 --- /dev/null +++ b/view/tpl/totp.tpl @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html data-bs-theme="light"> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"> + <head> + <link rel="stylesheet" href="/vendor/twbs/bootstrap/dist/css/bootstrap.min.css" type="text/css" media="screen"> + <link rel="stylesheet" href="/library/fork-awesome/css/fork-awesome.min.css" type="text/css" media="screen"> + </head> + <body> + <nav class="navbar bg-body-tertiary"> + <div class="container-sm"> + <span class="navbar-brand"><i class="fa fa-fw fa-hubzilla"></i>{{$header}}</span> + </div> + </nav> + <main class="container-sm mt-4"> + <h5>{{$id}}</h5> + <form action="totp_check" method="post"> + <input type="hidden" class="form-control" name="totp_code_static" value="1"/> + <div class="mb-3"> + <label for="totp-input" class="form-label">{{$desc}}</label> + <input id="totp-input" type="text" class="form-control" name="totp_code" value=""/> + </div> + <input type="submit" value="{{$submit}}" class="btn btn-primary"> + </form> + </main> + </body> +</html> diff --git a/view/tpl/totp_setup.tpl b/view/tpl/totp_setup.tpl new file mode 100644 index 000000000..6f995edf1 --- /dev/null +++ b/view/tpl/totp_setup.tpl @@ -0,0 +1,64 @@ +<div class="generic-content-wrapper"> + <div class="section-title-wrapper"> + <h2>{{$title}}</h2> + </div> + <div class="section-content-tools-wrapper"> + {{if $secret}} + <div class="section-content-info-wrapper"> + <div>{{$secret_text}}</div> + <div><strong class="text-break">{{$secret}}</strong></div> + </div> + {{/if}} + <img src="{{$qrcode}}" alt="{{$uri}}" title="{{$uri}}"> + <div id="mfa-test-wrapper" class="mb-3"> + <form action="" id="totp-test-form" method="post" autocomplete="off" > + <div class="mb-3"> + <label for="totp_test">{{$test_title}}</label> + <input type="text" id="totp_test" class="form-control" onfocus="totp_clear_code()"/> + <small class="text-muted">{{$test_title_sub}}</small> + </div> + <button id="otp-test-submit" type="submit" name="submit" class="btn btn-outline-primary" onclick="totp_test_code(); return false;"> + {{$test}} + </button> + </form> + </div> + <div id="mfa-submit-wrapper" class="{{if !$enable_mfa.2}}d-none{{/if}}"> + <form action="settings/multifactor" method="post"> + <input type='hidden' name='form_security_token' value='{{$form_security_token}}'> + {{include file="field_password.tpl" field=$password}} + {{include file="field_checkbox.tpl" field=$enable_mfa}} + <div class="settings-submit-wrapper" > + <button id="otp-enable-submit" type="b" name="submit" class="btn btn-primary"> + {{$submit}} + </button> + </div> + </form> + </div> + </div> +</div> + +<script> + function totp_clear_code() { + let box = document.getElementById('totp_test'); + box.value = ''; + box.focus(); + } + + function totp_test_code() { + $.post( + 'totp_check', + {totp_code: document.getElementById('totp_test').value}, + function(data) { + if (data['status']) { + $.jGrowl('{{$test_pass}}', { sticky: false, theme: 'info', life: 10000 }); + let e = document.getElementById('mfa-submit-wrapper'); + e.classList.remove('d-none'); + return; + } + $.jGrowl('{{$test_fail}}', { sticky: false, theme: 'notice', life: 10000 }); + } + ); + } +</script> + + |