Attachments, Emoji reactions, reply id's
FossilOrigin-Name: 58d7a2add5fc05eac12f8bacd7071095d91d0c9d3f481454202898b1cf5c115a
This commit is contained in:
parent
d46209f0ee
commit
025036832a
17 changed files with 186 additions and 26 deletions
23
perl/attachments.pm
Normal file
23
perl/attachments.pm
Normal 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
24
perl/emojis.pm
Normal 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'});
|
||||
}
|
||||
|
|
@ -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 => \¬ification_compact,
|
||||
notification_compact => \&generate_notification_compact,
|
||||
);
|
||||
|
||||
to_template(\%vars, \$data->{'main.tt'});
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
14
src/emoji.c
14
src/emoji.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
24
src/status.c
24
src/status.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
30
templates/attachment.tt
Normal 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
8
templates/emoji.tt
Normal 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 %]
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue