Attachments, Emoji reactions, reply id's

FossilOrigin-Name: 58d7a2add5fc05eac12f8bacd7071095d91d0c9d3f481454202898b1cf5c115a
This commit is contained in:
nekobit 2022-07-30 06:19:17 +00:00
parent d46209f0ee
commit 025036832a
17 changed files with 186 additions and 26 deletions

23
perl/attachments.pm Normal file
View File

@ -0,0 +1,23 @@
package attachments;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw( generate_attachment );
use template_helpers 'to_template';
sub generate_attachment
{
my ($ssn, $data, $att, $sensitive) = @_;
my %vars = (
prefix => '',
ssn => $ssn,
attachment => $att,
sensitive => $sensitive
);
to_template(\%vars, \$data->{'attachment.tt'});
}

24
perl/emojis.pm Normal file
View File

@ -0,0 +1,24 @@
package emojis;
use strict;
use warnings;
use Data::Dumper;
use Exporter 'import';
our @EXPORT = qw( generate_emoji );
use template_helpers 'to_template';
sub generate_emoji
{
my ($ssn, $data, $status_id, $emoji) = @_;
my %vars = (
prefix => '',
ssn => $ssn,
status_id => $status_id,
emoji => $emoji
);
to_template(\%vars, \$data->{'emoji.tt'});
}

View File

@ -3,9 +3,9 @@ use warnings;
# Modules
use Template;
use l10n qw( &lang %L10N );
use notifications qw( notification_compact );
use notifications qw( generate_notification_compact );
use template_helpers qw( &to_template );
use status ();
use status;
# my $template = Template->new(
# {
@ -33,7 +33,7 @@ sub base_page
acct => $ssn->{account},
data => $data,
notifs => $notifs,
notification_compact => \&notification_compact,
notification_compact => \&generate_notification_compact,
);
to_template(\%vars, \$data->{'main.tt'});

View File

@ -3,16 +3,17 @@ use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw( notification_compact );
our @EXPORT = qw( generate_notification_compact );
use template_helpers 'to_template';
sub notification_compact
sub generate_notification_compact
{
my ($ssn, $data, $notif) = @_;
my %vars = (
prefix => $ssn,
prefix => '',
ssn => $ssn,
notif => $notif
);

View File

@ -3,13 +3,15 @@ use strict;
use warnings;
use string_helpers qw( reltime_to_str );
use icons qw( get_icon visibility_to_icon );
use attachments 'generate_attachment';
use emojis 'generate_emoji';
use Exporter 'import';
our @EXPORT = qw( status );
our @EXPORT = qw( content_status generate_status );
use template_helpers 'to_template';
sub status
sub generate_status
{
my ($ssn, $data, $status) = @_;
@ -33,10 +35,13 @@ sub content_status
prefix => '',
ssn => $ssn,
data => $data,
create_status => \&status,
status => $status,
statuses_before => $statuses_before,
statuses_after => $statuses_after,
# Functions
create_status => \&generate_status,
make_att => \&generate_attachment,
make_emoji => \&generate_emoji,
);

View File

@ -199,10 +199,10 @@ char* construct_attachments(struct session* ssn,
HV* perlify_attachment(struct mstdnt_attachment* const attachment)
{
if (!attachments) return NULL;
if (!attachment) return NULL;
HV* attach_hv = newHV();
hvstores_str(attach_hv, "id", attachment->id);
hvstores_int(attach_hv, "type", attachment->type)
hvstores_int(attach_hv, "type", attachment->type);
hvstores_str(attach_hv, "url", attachment->url);
hvstores_str(attach_hv, "preview_url", attachment->preview_url);
hvstores_str(attach_hv, "remote_url", attachment->remote_url);

View File

@ -164,17 +164,15 @@ char* construct_emoji_picker(char* status_id, size_t* size)
return emoji_picker_html;
}
HV* perlify_emoji(struct mstdnt_emoji* const emoji);
HV* perlify_emoji(struct mstdnt_emoji* const emoji)
{
if (!emoji) return NULL;
HV* emoji_hv = newHV();
hvstores_str(emoji_hv, "shortcode", attachment->id);
hvstores_str(emoji_hv, "url", attachment->url);
hvstores_str(emoji_hv, "static_url", attachment->preview_url);
hvstores_str(emoji_hv, "visible_in_picker", attachment->visible_in_picker);
hvstores_str(emoji_hv, "hash", attachment->hash);
hvstores_str(emoji_hv, "description", attachment->description);
hvstores_str(emoji_hv, "blurhash", attachment->blurhash);
hvstores_str(emoji_hv, "shortcode", emoji->shortcode);
hvstores_str(emoji_hv, "url", emoji->url);
hvstores_str(emoji_hv, "static_url", emoji->static_url);
hvstores_str(emoji_hv, "visible_in_picker", emoji->visible_in_picker);
hvstores_str(emoji_hv, "category", emoji->category);
return emoji_hv;
}

View File

@ -86,3 +86,28 @@ char* construct_emoji_reactions(char* id, struct mstdnt_emoji_reaction* emos, si
return emos_view;
}
HV* perlify_emoji_reaction(struct mstdnt_emoji_reaction* const emoji)
{
if (!emoji) return NULL;
HV* emoji_hv = newHV();
hvstores_str(emoji_hv, "name", emoji->name);
hvstores_str(emoji_hv, "url", emoji->url);
hvstores_str(emoji_hv, "static_url", emoji->static_url);
hvstores_int(emoji_hv, "count", emoji->count);
hvstores_int(emoji_hv, "me", emoji->me);
return emoji_hv;
}
AV* perlify_emoji_reactions(struct mstdnt_emoji_reaction* const emos, size_t len)
{
if (!(emos && len)) return NULL;
AV* av = newAV();
av_extend(av, len-1);
for (int i = 0; i < len; ++i)
{
av_store(av, i, newRV_inc((SV*)perlify_emoji_reaction(emos + i)));
}
return av;
}

View File

@ -19,8 +19,13 @@
#ifndef EMOJI_REACTION_H
#define EMOJI_REACTION_H
#include <mastodont.h>
#include "global_perl.h"
char* construct_emoji_reaction(char* id, struct mstdnt_emoji_reaction* emo, size_t* str_len);
char* construct_emoji_reactions(char* id, struct mstdnt_emoji_reaction* emos, size_t emos_len, size_t* str_len);
// Perl
HV* perlify_emoji_reaction(struct mstdnt_emoji_reaction* const emoji);
AV* perlify_emoji_reactions(struct mstdnt_emoji_reaction* const emos, size_t len);
#endif // EMOJI_REACTION_H

View File

@ -23,6 +23,8 @@
#include "../templates/status.ctt"
#include "../templates/content_status.ctt"
#include "../templates/emoji_picker.ctt"
#include "../templates/attachment.ctt"
#include "../templates/emoji.ctt"
HV* template_files;
pthread_mutex_t perl_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -36,6 +38,8 @@ void init_template_files()
hv_stores(template_files, "status.tt", newSVpv(data_status_tt, data_status_tt_size));
hv_stores(template_files, "content_status.tt", newSVpv(data_content_status_tt, data_content_status_tt_size));
hv_stores(template_files, "emoji_picker.tt", newSVpv(data_emoji_picker_tt, data_emoji_picker_tt_size));
hv_stores(template_files, "attachment.tt", newSVpv(data_attachment_tt, data_attachment_tt_size));
hv_stores(template_files, "emoji.tt", newSVpv(data_emoji_tt, data_emoji_tt_size));
}
void cleanup_template_files()

View File

@ -84,7 +84,7 @@ void content_login_oauth(PATH_ARGS)
m_args.url = decode_url;
struct mstdnt_application_args args_app = {
.client_name = "Treebird",
.client_name = "DESU",
.redirect_uris = urlify_redirect_url,
.scopes = "read+write+follow+push",
.website = keystr(ssn->post.instance)

View File

@ -997,6 +997,24 @@ void notice_redirect(PATH_ARGS)
free(url);
}
HV* perlify_status_pleroma(const struct mstdnt_status_pleroma* pleroma)
{
if (!pleroma) return NULL;
HV* pleroma_hv = newHV();
hvstores_int(pleroma_hv, "conversation_id", pleroma->conversation_id);
hvstores_int(pleroma_hv, "direct_conversation_id", pleroma->direct_conversation_id);
hvstores_int(pleroma_hv, "thread_muted", pleroma->thread_muted);
hvstores_int(pleroma_hv, "local", pleroma->local);
hvstores_int(pleroma_hv, "parent_visible", pleroma->parent_visible);
hvstores_ref(pleroma_hv, "emoji_reactions",
perlify_emoji_reactions(pleroma->emoji_reactions, pleroma->emoji_reactions_len));
hvstores_str(pleroma_hv, "expires_at", pleroma->expires_at);
hvstores_str(pleroma_hv, "in_reply_to_account_acct", pleroma->in_reply_to_account_acct);
return pleroma_hv;
}
HV* perlify_status(const struct mstdnt_status* status)
{
if (!status) return NULL;
@ -1019,11 +1037,17 @@ HV* perlify_status(const struct mstdnt_status* status)
hvstores_int(status_hv, "muted", status->muted);
hvstores_int(status_hv, "bookmarked", status->bookmarked);
hvstores_int(status_hv, "pinned", status->pinned);
hvstores_int(status_hv, "sensitive", status->sensitive);
hvstores_int(status_hv, "visibility", ((int)(status->visibility)));
hvstores_int(status_hv, "reblogs_count", status->reblogs_count);
hvstores_int(status_hv, "favourites_count", status->favourites_count);
hvstores_int(status_hv, "replies_count", status->replies_count);
hvstores_ref(status_hv, "status", perlify_status(status->reblog));
hvstores_ref(status_hv, "media_attachments",
perlify_attachments(status->media_attachments, status->media_attachments_len));
hvstores_ref(status_hv, "emojis", perlify_emojis(status->emojis, status->emojis_len));
hvstores_ref(status_hv, "pleroma", perlify_status_pleroma(&(status->pleroma)));
return status_hv;
}

View File

@ -136,6 +136,7 @@ void notice_redirect(PATH_ARGS);
void api_status_interact(PATH_ARGS);
// Perl
HV* perlify_status_pleroma(const struct mstdnt_status_pleroma* pleroma);
HV* perlify_status(const struct mstdnt_status* status);
AV* perlify_statuses(const struct mstdnt_status* statuses, size_t len);

View File

@ -28,7 +28,7 @@
<label>
<input type="radio" name="visibility" value="direct" class="hidden" {{ %s : direct_checked }}>
<div class="visibility-icon vis-direct">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
</div>
</label>
<!-- Private -->

30
templates/attachment.tt Normal file
View File

@ -0,0 +1,30 @@
<div class="attachment-container
[%- IF attachment.type == 1 -%] [%# Image attachment %]
attachment-img">
<img width="256" src="[% attachment.url %]" loading="lazy">
[%- ELSIF attachment.type == 2 -%] [%# Gifv attachment (mastodon) %]
attachment-gifv">
<video width="256" autoplay muted loop>
<source src="[% attachment.url %]">
[ GIFV ]
</video>
[%- ELSIF attachment.type == 3 -%] [%# video attachment %]
attachment-video">
<video width="256" controls preload="metadata">
<source src="[% attachment.url %]">
[ VIDEO ]
</video>
[%- ELSIF attachment.type == 4 -%] [%# Audio attachment %]
attachment-audio">
<audio width="256" controls preload="metadata">
<source src="[% attachment.url %]">
</audio>
[%- ELSE -%] [%# Unknown attachment - Link %]
attachment-link [% IF sensitive %]sensitive[% END %]">
<a href="[% attachment.url %]">Attachment</a>
[%- END -%]
[% IF sensitive && attachment.type != 0 %] [%# Link %]
<div class="sensitive-contain sensitive"></div>
[% END %]
</div>

8
templates/emoji.tt Normal file
View File

@ -0,0 +1,8 @@
[%# So.. sometimes Pleroma just shows a `0` emoji count, I suppose when an instance gets blocked or the user deletes their account.
I'm not sure, but we should check if the emoji count is more than zero (as a workaround) or else it display's `0` %]
[% IF emoji.count > 0 %]
<a href="$prefix/status/[% status_id %]/react/[% emoji.name %]" class="emoji-react-box [% IF emoji.url %]custom-emoji-container[% END %] btn btn-alt [% IF emoji.me %]active[% END %]">
<span class="emoji">[%- IF emoji.url -%]<img src="[% emoji.url %]" class="custom-emoji-react">[%- ELSE -%][%- emoji.name -%][%- END -%]</span>
<span class="emoji-num">[% emoji.count %]</span>
</a>
[% END %]

View File

@ -52,20 +52,32 @@
[%# Note: The id may actually (99.5% of the time) be the acct %]
[% IF status.in_reply_to_id %]
<span class="in-reply-to">
<svg class="in-reply-to-icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 9l6 6-6 6"/><path d="M4 4v7a4 4 0 0 0 4 4h11"/></svg> <a class="in-reply-to-id" href="$prefix/status/[% status.in_reply_to_id %]#[% status.in_reply_to_id %]"> <span class="in-reply-to-text">In reply to</span> <span class="acct">[% status.in_reply_to_id %]</span></a>
<svg class="in-reply-to-icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 9l6 6-6 6"/><path d="M4 4v7a4 4 0 0 0 4 4h11"/></svg> <a class="in-reply-to-id" href="$prefix/status/[% status.in_reply_to_id %]#[% status.in_reply_to_id %]"> <span class="in-reply-to-text">In reply to</span> <span class="acct">[% status.pleroma.in_reply_to_account_acct || status.in_reply_to_account_id %]</span></a>
</span>
[% END %]
<span class="status-content">
[% status.content %]
</span>
{{%s:attachments}}
{{%s:interactions}}
{{%s:emoji_reactions}}
[% IF status.media_attachments %]
<div class="attachments">
[% FOR att IN status.media_attachments %]
[% make_att(ssn, data, att, status.sensitive) %]
[% END %]
</div>
[% END %]
[%# TODO {{%s:interactions}} %]
[% IF status.pleroma.emoji_reactions %]
<div class="emoji-reactions">
[% FOR emo IN status.pleroma.emoji_reactions %]
[% make_emoji(ssn, data, status.id, emo) %]
[% END %]
</div>
[% END %]
<div class="status-interact">
<table class="ui-table">
<tr>
<td>
<label for="status-quickreply-{{%s:status_id}}" class="pointer statbtn reply-btn">
<label for="status-quickreply-[% status.id %]" class="pointer statbtn reply-btn">
[% icon('reply') %]
[% IF status.replies_count %]
<span class="count">[% status.replies_count %]</span>