More notifications, errors, etc
FossilOrigin-Name: 052b9f7fbf6a43076c501922cc611b89949d24d03863ccb88dd0f910467eb1e2
This commit is contained in:
parent
c18179b52b
commit
997cce08f6
11 changed files with 179 additions and 20 deletions
81
dist/treebird.css
vendored
81
dist/treebird.css
vendored
|
@ -397,6 +397,28 @@ table.present th, table.present td
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fancy-error
|
||||
{
|
||||
margin: 36px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fancy-error-text
|
||||
{
|
||||
display: block;
|
||||
margin-top: 30px;
|
||||
font-size: 1.2rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.fancy-error-kaomoji
|
||||
{
|
||||
display: block;
|
||||
font-size: 2.4rem;
|
||||
color: #aaa;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.search-highlight
|
||||
{
|
||||
background-color: yellow;
|
||||
|
@ -588,10 +610,21 @@ input[type=submit].post-btn
|
|||
|
||||
.btn-single
|
||||
{
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #cacaca;
|
||||
}
|
||||
|
||||
.btn-small
|
||||
{
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.btn-single.btn-small
|
||||
{
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.sidebarbtn, .sidebarbtn:visited
|
||||
{
|
||||
display: block;
|
||||
|
@ -683,6 +716,12 @@ input[type=submit].post-btn
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* CSS issue, hope for the proposed $ selected :^) */
|
||||
.status.notification-info-lookahead
|
||||
{
|
||||
padding-top: 7px;
|
||||
}
|
||||
|
||||
.notification-info svg.like,
|
||||
.notification-info-format svg.like
|
||||
{
|
||||
|
@ -784,10 +823,20 @@ input[type=checkbox].hidden:not(:checked) + .reply-form
|
|||
display: inline;
|
||||
}
|
||||
|
||||
.notification-text-group-with-icon,
|
||||
.notification-text-group
|
||||
/* .notification-text-group-with-icon, */
|
||||
/* .notification-text-group */
|
||||
/* { */
|
||||
/* vertical-align: middle; */
|
||||
/* } */
|
||||
|
||||
.status.status-notification .status-content
|
||||
{
|
||||
vertical-align: middle;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.status.status-notification .status-interact
|
||||
{
|
||||
float: right;
|
||||
}
|
||||
|
||||
/***************************
|
||||
|
@ -1033,6 +1082,12 @@ input[type=checkbox].hidden:not(:checked) + .reply-form
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
.status .notification-text-group-with-icon .username
|
||||
{
|
||||
/* UNDO */
|
||||
vertical-align: unset;
|
||||
}
|
||||
|
||||
.status .status-content
|
||||
{
|
||||
margin: 4px 0 0 0;
|
||||
|
@ -1782,13 +1837,31 @@ input[type=radio].hidden:not(:checked) + .emoji-picker-emojos
|
|||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.simple-page h1
|
||||
.simple-page h1,
|
||||
.text-header
|
||||
{
|
||||
font-size: 1.5rem;
|
||||
padding-left: 12px;
|
||||
padding-bottom: 7px;
|
||||
border-bottom: 1px solid #cacaca;
|
||||
}
|
||||
|
||||
.text-header
|
||||
{
|
||||
padding-top: 10px;
|
||||
margin: 0;
|
||||
background-color: #f3f3f3;
|
||||
background: repeating-linear-gradient(
|
||||
-45deg,
|
||||
#efefef,
|
||||
#efefef 10px,
|
||||
#f6f6f6 10px,
|
||||
#f6f6f6 20px
|
||||
);
|
||||
box-shadow: inset 0px -2px 2px rgba(60, 60, 60, 0.2);
|
||||
text-shadow: 0px 2px 6px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.simple-page h3
|
||||
{
|
||||
margin-left: 15px;
|
||||
|
|
|
@ -73,7 +73,7 @@ our %L10N = (
|
|||
LOGIN_HEADER => 'Login / Register',
|
||||
LOGIN_FAIL => 'Couldn\'t login',
|
||||
NOTIF_LIKED => 'liked your status',
|
||||
NOTIF_REACTED_WITH => 'reacted with %s',
|
||||
NOTIF_REACTED_WITH => 'reacted with',
|
||||
NOTIF_REPEATED => 'repeated your status',
|
||||
NOTIF_FOLLOW => 'followed you',
|
||||
NOTIF_FOLLOW_REQUEST => 'wants to follow you',
|
||||
|
|
|
@ -6,6 +6,8 @@ use Exporter 'import';
|
|||
our @EXPORT = qw( generate_notification_compact content_notifications );
|
||||
|
||||
use template_helpers 'to_template';
|
||||
use status 'generate_status';
|
||||
use string_helpers qw( random_error_kaomoji );
|
||||
|
||||
sub generate_notification_compact
|
||||
{
|
||||
|
@ -26,8 +28,10 @@ sub content_notifications
|
|||
|
||||
my %vars = (
|
||||
prefix => '',
|
||||
ssn=> $ssn,
|
||||
notifs => $notifs
|
||||
ssn => $ssn,
|
||||
notifs => $notifs,
|
||||
create_status => sub { generate_status($ssn, $data, shift, shift); },
|
||||
random_error_kaomoji => \&random_error_kaomoji,
|
||||
);
|
||||
|
||||
to_template(\%vars, \$data->{'content_notifs.tt'});
|
||||
|
|
|
@ -7,6 +7,7 @@ use attachments 'generate_attachment';
|
|||
use postbox 'generate_postbox';
|
||||
use emojis 'generate_emoji';
|
||||
use Exporter 'import';
|
||||
use l10n 'lang';
|
||||
|
||||
our @EXPORT = qw( content_status generate_status );
|
||||
|
||||
|
@ -14,7 +15,7 @@ use template_helpers 'to_template';
|
|||
|
||||
sub generate_status
|
||||
{
|
||||
my ($ssn, $data, $status) = @_;
|
||||
my ($ssn, $data, $status, $notif) = @_;
|
||||
my $boost_acct;
|
||||
|
||||
# Move status reference for boosts and keep account
|
||||
|
@ -29,10 +30,12 @@ sub generate_status
|
|||
prefix => '',
|
||||
ssn => $ssn,
|
||||
status => $status,
|
||||
boost => $boost_acct,
|
||||
boost => $boost_acct, # May be undef
|
||||
data => $data,
|
||||
notif => $notif, # May be undef
|
||||
# Functions
|
||||
icon => \&get_icon,
|
||||
lang => \&lang,
|
||||
rel_to_str => \&reltime_to_str,
|
||||
vis_to_icon => \&visibility_to_icon,
|
||||
make_att => \&generate_attachment,
|
||||
|
|
|
@ -3,7 +3,7 @@ use strict;
|
|||
use warnings;
|
||||
use Exporter 'import';
|
||||
|
||||
our @EXPORT = qw( reltime_to_str greentextify emojify format_username get_mentions_from_content localize_mentions simple_escape );
|
||||
our @EXPORT = qw( reltime_to_str greentextify emojify format_username get_mentions_from_content localize_mentions simple_escape random_error_kaomoji );
|
||||
|
||||
my $re_mentions = '(?=<a .*?mention.*?)<a .*?href="https?:\/\/(.*?)\/(?:@|users\/|\/u)?(.*?)?".*?>';
|
||||
|
||||
|
@ -86,3 +86,15 @@ sub get_mentions_from_content
|
|||
($status->{account}->{acct} eq $ssn->{account}->{acct})
|
||||
? $result : '@' . $status->{account}->{acct} . ' ' . $result;
|
||||
}
|
||||
|
||||
sub random_error_kaomoji
|
||||
{
|
||||
my @messages = (
|
||||
"(; ̄Д ̄)",
|
||||
"(`Δ´)!",
|
||||
"¯\\_(ツ)_/¯",
|
||||
"(ノ´・ω・)ノ ミ ┸━┸",
|
||||
"(╯°□°)╯︵ ┻━┻",
|
||||
);
|
||||
@messages[rand(scalar @messages)];
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ static struct path_info paths[] = {
|
|||
{ "/blocked", content_account_blocked },
|
||||
{ "/muted", content_account_muted },
|
||||
{ "/notifications_compact", content_notifications_compact },
|
||||
{ "/notifications/clear", content_notifications_clear },
|
||||
{ "/notifications", content_notifications },
|
||||
{ "/tag/:", content_tl_tag },
|
||||
{ "/chats/:", content_chat_view },
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "string_helpers.h"
|
||||
#include "easprintf.h"
|
||||
#include "navigation.h"
|
||||
#include "http.h"
|
||||
#include "status.h"
|
||||
#include "error.h"
|
||||
#include "emoji.h"
|
||||
|
@ -225,7 +226,8 @@ void content_notifications(PATH_ARGS)
|
|||
HV* session_hv = perlify_session(ssn);
|
||||
XPUSHs(newRV_noinc((SV*)session_hv));
|
||||
XPUSHs(newRV_noinc((SV*)template_files));
|
||||
XPUSHs(newRV_noinc((SV*)perlify_notifications(notifs, notifs_len)));
|
||||
if (notifs)
|
||||
XPUSHs(newRV_noinc((SV*)perlify_notifications(notifs, notifs_len)));
|
||||
|
||||
// ARGS
|
||||
PUTBACK;
|
||||
|
@ -331,6 +333,19 @@ void content_notifications_compact(PATH_ARGS)
|
|||
free(theme_str);
|
||||
}
|
||||
|
||||
void content_notifications_clear(PATH_ARGS)
|
||||
{
|
||||
char* referer = GET_ENV("HTTP_REFERER", req);
|
||||
struct mstdnt_args m_args;
|
||||
set_mstdnt_args(&m_args, ssn);
|
||||
struct mstdnt_storage storage = { 0 };
|
||||
|
||||
mastodont_notifications_clear(api, &m_args, &storage);
|
||||
|
||||
mastodont_storage_cleanup(&storage);
|
||||
redirect(req, REDIRECT_303, referer);
|
||||
}
|
||||
|
||||
// Converts it into a perl struct
|
||||
HV* perlify_notification(struct mstdnt_notification* notif)
|
||||
{
|
||||
|
@ -339,6 +354,8 @@ HV* perlify_notification(struct mstdnt_notification* notif)
|
|||
|
||||
hvstores_str(notif_hv, "id", notif->id);
|
||||
hvstores_str(notif_hv, "created_at", notif->created_at);
|
||||
hvstores_str(notif_hv, "emoji", notif->emoji);
|
||||
hvstores_str(notif_hv, "type", mstdnt_notification_t_to_str(notif->type));
|
||||
hvstores_ref(notif_hv, "account", perlify_account(notif->account));
|
||||
hvstores_ref(notif_hv, "status", perlify_status(notif->status));
|
||||
|
||||
|
@ -363,4 +380,5 @@ AV* perlify_notifications(struct mstdnt_notification* notifs, size_t len)
|
|||
void api_notifications(PATH_ARGS)
|
||||
{
|
||||
send_result(req, NULL, "application/json", "{\"status\":0}", 0);
|
||||
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ char* construct_notifications_compact(struct session* ssn,
|
|||
// Page contents
|
||||
void content_notifications(PATH_ARGS);
|
||||
void content_notifications_compact(PATH_ARGS);
|
||||
void content_notifications_clear(PATH_ARGS);
|
||||
|
||||
void api_notifications(PATH_ARGS);
|
||||
|
||||
|
|
|
@ -1 +1,29 @@
|
|||
<h1>Notifications</h1>
|
||||
<h1 class="text-header">Notifications</h1>
|
||||
<div class="menubar">
|
||||
<a class="btn btn-single btn-small" href="/notifications/clear">Clear notifications</a>
|
||||
</div>
|
||||
[% IF notifs %]
|
||||
[% FOREACH notif IN notifs %]
|
||||
[%# There are 3 types of "different" notifications to render
|
||||
- Mention, statuses (just regular statuses)
|
||||
- Favorites, moves, reblogs, polls (no interaction buttons)
|
||||
- Follows, follow requests
|
||||
%]
|
||||
[% IF notif.type == 'mention' ||
|
||||
notif.type == 'status' %]
|
||||
[% create_status(notif.status) %]
|
||||
[% ELSIF notif.type == 'favourite' ||
|
||||
notif.type == 'reblog' ||
|
||||
notif.type == 'emoji reaction' ||
|
||||
notif.type == 'poll' %]
|
||||
[% create_status(notif.status, notif) %]
|
||||
[% ELSIF notif.type == 'follow' || notif.type == 'follow request' %]
|
||||
Someone attempted to follow you
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% ELSE %]
|
||||
<div class="fancy-error">
|
||||
<span class="fancy-error-kaomoji">[% random_error_kaomoji() %]</span>
|
||||
<span class="fancy-error-text">No notifications.</span>
|
||||
</div>
|
||||
[% END %]
|
||||
|
|
|
@ -1,14 +1,31 @@
|
|||
<input type="checkbox" class="status-hide" id="status-toggle-[% status.id %]"[% IF status.muted %] checked[% END %]>
|
||||
<div class="status" id="[% status.id %]">
|
||||
[% IF boost %]
|
||||
<div class="status
|
||||
[%- IF notif %] status-notification[% END %]
|
||||
[%# Blame CSS for this class %]
|
||||
[%- IF boost || (notif && notif.account) %] notification-info-lookahead[% END -%]
|
||||
" id="[% status.id %]">
|
||||
[% IF boost || (notif && notif.account) %]
|
||||
<div class="notification-info">
|
||||
<img src="[% boost.avatar %]" loading="lazy" class="avatar">
|
||||
<img src="[% boost.avatar || notif.account.avatar %]" loading="lazy" class="avatar">
|
||||
<div class="notification-user">
|
||||
<span class="notification-text-group-with-icon">
|
||||
<span class="username">[% format_username(boost) %]</span>
|
||||
<span class="action">repeated</span>
|
||||
<span class="username">[% format_username(boost || notif.account) %]</span>
|
||||
<span class="action">
|
||||
[% IF notif && notif.type == 'favourite' %]
|
||||
[% lang('NOTIF_LIKED') %]
|
||||
[% ELSIF boost || (notif && notif.type == 'reblog') %]
|
||||
[% lang('NOTIF_REPEATED') %]
|
||||
[% ELSIF boost || (notif && notif.type == 'emoji reaction') %]
|
||||
[%# Yes, it can be a custom emoji too %]
|
||||
[% lang('NOTIF_REACTED_WITH') %] [% notif.emoji %]
|
||||
[% END %]
|
||||
</span>
|
||||
</span>
|
||||
[% icon('repeat') %]
|
||||
[% IF notif && notif.type == 'favourite' %]
|
||||
[% icon('favourite') %]
|
||||
[% ELSIF boost || (notif && notif.type == 'boost') %] [%# It's a repeat %]
|
||||
[% icon('repeat') %]
|
||||
[% END %]
|
||||
</div>
|
||||
</div>
|
||||
[% END %]
|
||||
|
@ -88,6 +105,7 @@
|
|||
</div>
|
||||
[% END %]
|
||||
<div class="status-interact">
|
||||
[% UNLESS notif %]
|
||||
<div class="status-buttons">
|
||||
<label for="status-quickreply-[% status.id %]" class="pointer statbtn reply-btn">
|
||||
[% icon('reply') %]
|
||||
|
@ -132,13 +150,14 @@
|
|||
[% emoji_picker %]
|
||||
[%- END %]
|
||||
</div>
|
||||
[% END %]
|
||||
[%# Put these at the end, incase someone wants to move status icons to the beginning (this makes it easier %]
|
||||
<a target="_parent" href="$prefix/status/[% status.id %]#[% status.id %]" class="pointer statbtn view-btn">
|
||||
[% icon('expand') %]
|
||||
</a>
|
||||
<span class="status-meta">
|
||||
<a href="#[% status.id %]" title="[% time_to_str(status.created_at) %]" class="time">[%- rel_to_str(status.created_at) -%]</a>
|
||||
[% IF status.application && status.application.name %]
|
||||
[% IF status.application && status.application.name && !notif %]
|
||||
[% IF status.application.url %]
|
||||
<a class="application-name" href="[% status.application.url %]">[% status.application.name %]</a>
|
||||
[% ELSE %]
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<option value="1">Self</option>
|
||||
<option value="2">Following</option>
|
||||
</select>
|
||||
<input type="submit" value="Filter">
|
||||
<input type="submit" class="btn btn-single" value="Filter">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in a new issue