Notifications perlify

FossilOrigin-Name: 0d65589909abc6c72911d68ef4c03f48c7d3f552ba5c82d681964eefbf8a2128
This commit is contained in:
nekobit 2022-07-26 22:04:44 +00:00
parent 5b9c7d75f5
commit a90878c1b8
10 changed files with 303 additions and 176 deletions

View file

@ -3,7 +3,7 @@ use warnings;
# Modules
use Template;
use l10n qw( %L10N );
use notifications qw( &notifs_compact );
use notifications qw( notification_compact );
use template_helpers qw( &to_template );
# my $template = Template->new(
@ -28,7 +28,8 @@ sub base_page
sidebar_opacity => $ssn->{config}->{sidebar_opacity} / 255,
acct => $ssn->{account},
data => $data,
notifs => $notifs
notifs => $notifs,
notification_compact => \&notification_compact,
);
to_template(\%vars, \$data->{'main.tt'});

View file

@ -1,11 +1,19 @@
package Notifications;
package notifications;
use Exporter 'import';
our @EXPORT = qw( &notifs_compact );
our @EXPORT = qw( notification_compact );
sub notifs_compact
use template_helpers 'to_template';
sub notification_compact
{
# my ($template, ) = @_;
1;
my ($ssn, $data, $notif) = @_;
my %vars = (
prefix => $ssn,
notif => $notif
);
to_template(\%vars, \$data->{'notif_compact.tt'});
}

19
perl/status.pm Normal file
View file

@ -0,0 +1,19 @@
package status;
use Exporter 'import';
our @EXPORT = qw( status );
use template_helpers 'to_template';
sub status
{
my ($ssn, $data, $status) = @_;
my %vars = (
prefix => $ssn,
status => $status
);
to_template(\%vars, \$data->{'status.tt'});
}

View file

@ -39,57 +39,56 @@
void render_base_page(struct base_page* page, FCGX_Request* req, struct session* ssn, mastodont_t* api)
{
struct mstdnt_args m_args;
set_mstdnt_args(&m_args, ssn);
struct mstdnt_storage storage = { 0 };
struct mstdnt_notification* notifs = NULL;
size_t notifs_len = 0;
// Fetch notification (if not iFrame)
if (keystr(ssn->cookies.logged_in) && keystr(ssn->cookies.access_token) &&
!ssn->config.notif_embed)
{
struct mstdnt_get_notifications_args args = {
.exclude_types = 0,
.account_id = NULL,
.exclude_visibilities = 0,
.include_types = 0,
.with_muted = 1,
.max_id = NULL,
.min_id = NULL,
.since_id = NULL,
.offset = 0,
.limit = 8,
};
mastodont_get_notifications(
api,
&m_args,
&args,
&storage,
&notifs,
&notifs_len
);
}
// Init perl stack
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
struct mstdnt_args m_args;
set_mstdnt_args(&m_args, ssn);
HV* session_hv = perlify_session(ssn);
XPUSHs(sv_2mortal(newRV_inc((SV*)session_hv)));
XPUSHs(sv_2mortal(newRV_inc((SV*)template_files)));
XPUSHs(sv_2mortal(newSVpv(page->content, 0)));
if (keystr(ssn->cookies.logged_in) && keystr(ssn->cookies.access_token))
if (notifs && notifs_len)
{
// Get / Show notifications on sidebar
if (!ssn->config.notif_embed)
{
struct mstdnt_storage storage = { 0 };
struct mstdnt_notification* notifs = NULL;
size_t notifs_len = 0;
struct mstdnt_get_notifications_args args = {
.exclude_types = 0,
.account_id = NULL,
.exclude_visibilities = 0,
.include_types = 0,
.with_muted = 1,
.max_id = NULL,
.min_id = NULL,
.since_id = NULL,
.offset = 0,
.limit = 8,
};
if (mastodont_get_notifications(api,
&m_args,
&args,
&storage,
&notifs,
&notifs_len) == 0)
{
AV* notifs_av = perlify_notifications(notifs, notifs_len);
XPUSHs(sv_2mortal(newRV_inc((SV*)notifs_av)));
}
mstdnt_cleanup_notifications(notifs, notifs_len);
mastodont_storage_cleanup(&storage);
}
AV* notifs_av = perlify_notifications(notifs, notifs_len);
XPUSHs(sv_2mortal(newRV_inc((SV*)notifs_av)));
}
else XPUSHs(&PL_sv_undef);
// Run function
PUTBACK;
call_pv("base_page", G_SCALAR);
@ -102,6 +101,9 @@ cleanup:
PUTBACK;
FREETMPS;
LEAVE;
mstdnt_cleanup_notifications(notifs, notifs_len);
mastodont_storage_cleanup(&storage);
}
void send_result(FCGX_Request* req, char* status, char* content_type, char* data, size_t data_len)

View file

@ -17,7 +17,10 @@
*/
#include "global_perl.h"
#include "../templates/main.ctt"
#include "../templates/notif_compact.ctt"
#include "../templates/status.ctt"
const HV* template_files;
@ -26,6 +29,8 @@ void init_template_files()
template_files = newHV();
hv_stores(template_files, "main.tt", newSVpv(data_main_tt, data_main_tt_size));
hv_stores(template_files, "notif_compact.tt", newSVpv(data_notif_compact_tt, data_notif_compact_tt_size));
hv_stores(template_files, "status.tt", newSVpv(data_status_tt, data_status_tt_size));
}
void cleanup_template_files()

View file

@ -1041,86 +1041,87 @@ void content_status_interactions(FCGX_Request* req,
void content_status(PATH_ARGS, uint8_t flags)
{
struct mstdnt_args m_args;
set_mstdnt_args(&m_args, ssn);
char* output;
// Status context
struct mstdnt_storage storage = {0}, status_storage = {0};
struct mstdnt_status* statuses_before = NULL,
*statuses_after = NULL,
status = { 0 };
size_t stat_before_len = 0, stat_after_len = 0;
char* before_html = NULL, *stat_html = NULL, *after_html = NULL, *stat_reply = NULL,
* thread_pagination = NULL;
/* struct mstdnt_args m_args; */
/* set_mstdnt_args(&m_args, ssn); */
/* char* output; */
/* // Status context */
/* struct mstdnt_storage storage = {0}, status_storage = {0}; */
/* struct mstdnt_status* statuses_before = NULL, */
/* *statuses_after = NULL, */
/* status = { 0 }; */
/* size_t stat_before_len = 0, stat_after_len = 0; */
/* char* before_html = NULL, *stat_html = NULL, *after_html = NULL, *stat_reply = NULL, */
/* * thread_pagination = NULL; */
int stat_after_limit = 15;
int stat_before_limit = 15;
#define enough_statuses_before (stat_before_len > stat_before_limit)
#define enough_statuses_after (stat_after_len > stat_after_limit)
/* int stat_after_limit = 15; */
/* int stat_before_limit = 15; */
/* #define enough_statuses_before (stat_before_len > stat_before_limit) */
/* #define enough_statuses_after (stat_after_len > stat_after_limit) */
try_post_status(ssn, api);
mastodont_get_status_context(api,
&m_args,
data[0],
&storage,
&statuses_before, &statuses_after,
&stat_before_len, &stat_after_len);
/* try_post_status(ssn, api); */
/* mastodont_get_status_context(api, */
/* &m_args, */
/* data[0], */
/* &storage, */
/* &statuses_before, &statuses_after, */
/* &stat_before_len, &stat_after_len); */
// Get information
if (mastodont_get_status(api, &m_args, data[0], &status_storage, &status))
{
stat_html = construct_error("Status not found", E_ERROR, 1, NULL);
}
else {
before_html = construct_statuses(ssn, api,
(enough_statuses_before ?
statuses_before + (stat_before_len - stat_before_limit) : statuses_before),
(enough_statuses_before ?
stat_before_limit : stat_before_len),
NULL, 0);
/* // Get information */
/* if (mastodont_get_status(api, &m_args, data[0], &status_storage, &status)) */
/* { */
/* stat_html = construct_error("Status not found", E_ERROR, 1, NULL); */
/* } */
/* else { */
/* before_html = construct_statuses(ssn, api, */
/* (enough_statuses_before ? */
/* statuses_before + (stat_before_len - stat_before_limit) : statuses_before), */
/* (enough_statuses_before ? */
/* stat_before_limit : stat_before_len), */
/* NULL, 0); */
// Current status
stat_html = construct_status(ssn, api, &status, NULL, NULL, NULL, flags);
if ((flags & STATUS_REPLY) == STATUS_REPLY)
{
stat_reply = reply_status(ssn,
data[0],
&status);
}
}
/* // Current status */
/* stat_html = construct_status(ssn, api, &status, NULL, NULL, NULL, flags); */
/* if ((flags & STATUS_REPLY) == STATUS_REPLY) */
/* { */
/* stat_reply = reply_status(ssn, */
/* data[0], */
/* &status); */
/* } */
/* } */
// After...
// For pagination, we already start at the first, so no math required here
after_html = construct_statuses(ssn, api, statuses_after,
(enough_statuses_after ? stat_after_limit : stat_after_len),
NULL, 0);
/* // After... */
/* // For pagination, we already start at the first, so no math required here */
/* after_html = construct_statuses(ssn, api, statuses_after, */
/* (enough_statuses_after ? stat_after_limit : stat_after_len), */
/* NULL, 0); */
// Thread pagination buttons
if (statuses_before || statuses_after)
{
struct thread_page_btn_template pagination_tmpl = {
.prefix = config_url_prefix,
.status_first = (statuses_before ? statuses_before[0].id : "deadbeef"),
.status_last = (statuses_after ? statuses_after[stat_after_len-1].id : "deadbeef"),
.status_before = (statuses_before && enough_statuses_before ? statuses_before[stat_before_len - stat_before_limit].id : "deadbeef"),
.status_after = (statuses_after && enough_statuses_after ?
statuses_after[stat_after_limit].id : "deadbeef"),
};
thread_pagination = tmpl_gen_thread_page_btn(&pagination_tmpl, NULL);
}
/* // Thread pagination buttons */
/* if (statuses_before || statuses_after) */
/* { */
/* struct thread_page_btn_template pagination_tmpl = { */
/* .prefix = config_url_prefix, */
/* .status_first = (statuses_before ? statuses_before[0].id : "deadbeef"), */
/* .status_last = (statuses_after ? statuses_after[stat_after_len-1].id : "deadbeef"), */
/* .status_before = (statuses_before && enough_statuses_before ? statuses_before[stat_before_len - stat_before_limit].id : "deadbeef"), */
/* .status_after = (statuses_after && enough_statuses_after ? */
/* statuses_after[stat_after_limit].id : "deadbeef"), */
/* }; */
/* thread_pagination = tmpl_gen_thread_page_btn(&pagination_tmpl, NULL); */
/* } */
easprintf(&output, "%s%s%s%s%s%s",
thread_pagination ? thread_pagination : "",
before_html ? before_html : "",
stat_html ? stat_html : "",
stat_reply ? stat_reply : "",
after_html ? after_html : "",
thread_pagination ? thread_pagination : "");
/* easprintf(&output, "%s%s%s%s%s%s", */
/* thread_pagination ? thread_pagination : "", */
/* before_html ? before_html : "", */
/* stat_html ? stat_html : "", */
/* stat_reply ? stat_reply : "", */
/* after_html ? after_html : "", */
/* thread_pagination ? thread_pagination : ""); */
struct base_page b = {
.category = BASE_CAT_NONE,
.content = output,
.content = "test",
.sidebar_left = NULL
};
@ -1128,18 +1129,18 @@ void content_status(PATH_ARGS, uint8_t flags)
render_base_page(&b, req, ssn, api);
// Cleanup
free(before_html);
free(stat_html);
free(after_html);
free(output);
free(thread_pagination);
if ((flags & STATUS_REPLY) == STATUS_REPLY)
free(stat_reply);
mstdnt_cleanup_statuses(statuses_before, stat_before_len);
mstdnt_cleanup_statuses(statuses_after, stat_after_len);
mstdnt_cleanup_status(&status);
mastodont_storage_cleanup(&storage);
mastodont_storage_cleanup(&status_storage);
/* free(before_html); */
/* free(stat_html); */
/* free(after_html); */
/* free(output); */
/* free(thread_pagination); */
/* if ((flags & STATUS_REPLY) == STATUS_REPLY) */
/* free(stat_reply); */
/* mstdnt_cleanup_statuses(statuses_before, stat_before_len); */
/* mstdnt_cleanup_statuses(statuses_after, stat_after_len); */
/* mstdnt_cleanup_status(&status); */
/* mastodont_storage_cleanup(&storage); */
/* mastodont_storage_cleanup(&status_storage); */
}
void notice_redirect(PATH_ARGS)

View file

@ -1,53 +1,53 @@
<input type="checkbox" class="status-hide" id="status-toggle-{{%s:status_id}}" {{ %s:thread_hidden }}>
<div class="status" id="{{%s:status_id}}">
{{ %s : notif_info }}
<table class="status-table ui-table">
<tr>
<td class="pfp-td {{%s:is_cat}} {{%s:is_bun}}">
<img src="{{%s:avatar}}" loading="lazy">
</td>
<td class="status-info">
<div class="poster-stats">
<span class="username">{{%s:username}}</span>
<a class="instance-info" href="{{%s:prefix}}/@{{%s:acct}}">{{%s:acct}}</a>
<span class="alignend">
<div class="menu-container status-visibility">
{{%s:visibility}}
<div class="menu">
<ul>
<li>
<form action="{{%s:prefix}}/status/{{%s:status_id}}/interact" method="post">
<input type="hidden" name="itype" value="{{%s:unmute}}mute">
<input type="submit" class="btn-menu" value="{{%s:unmute_btn}}">
</form>
</li>
<li>
<form action="{{%s:prefix}}/status/{{%s:status_id}/interact" method="post">
<input type="hidden" name="itype" value="{{%s:unbookmark}}bookmark">
<input type="submit" class="btn-menu" value="{{%s:unbookmark_btn}}">
</form>
</li>
{{%s:pin_status}}
{{%s:delete_status}}
</ul>
</div>
</div>
<label for="status-toggle-{{%s:status_id}}" class="status-view"></label>
</span>
</div>
<div class="status-data">
{{%s:in_reply_to_str}}
<span class="status-content">
{{%s:status_content}}
</span>
{{%s:attachments}}
{{%s:interactions}}
{{%s:emoji_reactions}}
{{%s:interaction_btns}}
</div>
</td>
</tr>
</table>
{{ %s : notif_info }}
<table class="status-table ui-table">
<tr>
<td class="pfp-td {{%s:is_cat}} {{%s:is_bun}}">
<img src="{{%s:avatar}}" loading="lazy">
</td>
<td class="status-info">
<div class="poster-stats">
<span class="username">{{%s:username}}</span>
<a class="instance-info" href="{{%s:prefix}}/@{{%s:acct}}">{{%s:acct}}</a>
<span class="alignend">
<div class="menu-container status-visibility">
{{%s:visibility}}
<div class="menu">
<ul>
<li>
<form action="{{%s:prefix}}/status/{{%s:status_id}}/interact" method="post">
<input type="hidden" name="itype" value="{{%s:unmute}}mute">
<input type="submit" class="btn-menu" value="{{%s:unmute_btn}}">
</form>
</li>
<li>
<form action="{{%s:prefix}}/status/{{%s:status_id}/interact" method="post">
<input type="hidden" name="itype" value="{{%s:unbookmark}}bookmark">
<input type="submit" class="btn-menu" value="{{%s:unbookmark_btn}}">
</form>
</li>
{{%s:pin_status}}
{{%s:delete_status}}
</ul>
</div>
</div>
<label for="status-toggle-{{%s:status_id}}" class="status-view"></label>
</span>
</div>
<div class="status-data">
{{%s:in_reply_to_str}}
<span class="status-content">
{{%s:status_content}}
</span>
{{%s:attachments}}
{{%s:interactions}}
{{%s:emoji_reactions}}
{{%s:interaction_btns}}
</div>
</td>
</tr>
</table>
</div>
<input type="checkbox" class="quickreply-hide hidden" id="status-quickreply-{{%s:status_id}}">
{{ %s : reply }}

View file

@ -122,6 +122,12 @@
</tr>
</table>
</div>
<!-- Notifications -->
[% FOREACH notif IN notifs %]
[% notification_compact(ssn, data, notif) %]
[% END %]
[% ELSE %]
<div class="sidebar-login">
<form action="$prefix/login" method="post">

View file

@ -0,0 +1,17 @@
<table class="notification-compact notification ui-table">
<tr>
<td class="pfp-compact-td">
<img src="[% notif.account.avatar %]">
</td>
<td>
<div class="notification-info">
<span class="notification-text-group">
<span title="[% notif.account.acct %]" class="username">[% notif.account.display_name %]</span>
<span class="action">{{%s:action}}</span>
</span> {{%s:notif_svg}}
</div>
<div class="notification-content {{%s:is_status}}">{{%s:content}}</div>
<div class="notification-stats">{{%s:stats}}</div>
</td>
</tr>
</table>

68
templates/status.tt Normal file
View file

@ -0,0 +1,68 @@
<input type="checkbox" class="status-hide" id="status-toggle-[% status.id %]" {{ %s:thread_hidden }}>
<div class="status" id="[% status.id %]">
[% notif_info %]
<table class="status-table ui-table">
<tr>
<td class="pfp-td {{%s:is_cat}} {{%s:is_bun}}">
<img src="{{%s:avatar}}" loading="lazy">
</td>
<td class="status-info">
<div class="poster-stats">
<span class="username">[% status.account.display_name %]</span>
<a class="instance-info" href="$prefix/@{{%s:acct}}">[% status.account.acct %]</a>
<span class="alignend">
<div class="menu-container status-visibility">
{{%s:visibility}}
<div class="menu">
<ul>
<li>
<form action="$prefix/status/[% status.id %]/interact" method="post">
<input type="hidden" name="itype" value="mute">
<input type="submit" class="btn-menu" value="{{%s:unmute_btn}}">
</form>
</li>
<li>
<form action="$prefix/status/[% status.id %]/interact" method="post">
<input type="hidden" name="itype" value="bookmark">
<input type="submit" class="btn-menu" value="{{%s:unbookmark_btn}}">
</form>
</li>
[%# pin %]
<li>
<form action="$prefix/status/[% status.id %]/interact" method="post">
<input type="hidden" name="itype" value="pin">
<input type="submit" class="btn-menu" value="{{%s:text}}">
</form>
</li>
[%# Delete %]
<li>
<form action="$prefix/status/[% status.id %]/interact" method="post">
<input type="hidden" name="itype" value="delete">
<input type="submit" class="btn-menu" value="{{%s:text}}">
</form>
</li>
</ul>
</div>
</div>
<label for="status-toggle-[% status.id %]" class="status-view"></label>
</span>
</div>
<div class="status-data">
[%# Note: The id may actually (99.5% of the time) be the acct %]
[% status.in_reply_to_id %]
<span class="status-content">
[% status.content %]
</span>
{{%s:attachments}}
{{%s:interactions}}
{{%s:emoji_reactions}}
{{%s:interaction_btns}}
</div>
</td>
</tr>
</table>
</div>
<input type="checkbox" class="quickreply-hide hidden" id="status-quickreply-[% status.id %]">
{{ %s : reply }}