diff --git a/src/Controller/FediPlanController.php b/src/Controller/FediPlanController.php index 1990874..ebca7bf 100644 --- a/src/Controller/FediPlanController.php +++ b/src/Controller/FediPlanController.php @@ -100,6 +100,10 @@ class FediPlanController extends AbstractController $form->get('code')->addError(new FormError($translator->trans('error.instance.mastodon_account', [], 'fediplan', 'en'))); } else { $account = $mastodon_api->getSingleAccount($accountReply['response']); + $instanceReply = $mastodon_api->get_instance(); + $instance = $mastodon_api->getInstanceConfiguration($instanceReply['response']); + $session = $request->getSession(); + $session->set("instance",$instance); $account->setInstance($host); $account->setToken($token_type . " " . $access_token); $token = new UsernamePasswordToken($account, 'main', array('ROLE_USER')); diff --git a/src/Form/PollOptionType.php b/src/Form/PollOptionType.php index 87337c3..08317f1 100644 --- a/src/Form/PollOptionType.php +++ b/src/Form/PollOptionType.php @@ -7,11 +7,14 @@ namespace App\Form; +use App\SocialEntity\Instance; use App\SocialEntity\PollOption; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class PollOptionType extends AbstractType @@ -19,18 +22,21 @@ class PollOptionType extends AbstractType private Security $securityContext; + private Instance $instance; - public function __construct(Security $securityContext) + public function __construct(Security $securityContext, RequestStack $requestStack) { $this->securityContext = $securityContext; + $this->instance = $requestStack->getSession()->get('instance'); } public function buildForm(FormBuilderInterface $builder, array $options): void { + $max_char = $this->instance->getConfiguration()->getPolls()->getMaxCharactersPerOption(); $builder->add('title', TextType::class, [ 'required' => false, - 'attr' => ['class' => 'form-control'], + 'attr' => ['class' => 'form-control', 'maxlength' => $max_char], 'label' => 'page.schedule.form.poll_item', ]); } diff --git a/src/Services/Mastodon_api.php b/src/Services/Mastodon_api.php index fcf678e..dbebfcb 100644 --- a/src/Services/Mastodon_api.php +++ b/src/Services/Mastodon_api.php @@ -15,13 +15,18 @@ use App\Security\MastodonAccount; use App\Services\Curl as Curl; use App\SocialEntity\Application; use App\SocialEntity\Attachment; +use App\SocialEntity\Configuration; use App\SocialEntity\CustomField; use App\SocialEntity\Emoji; +use App\SocialEntity\Instance; +use App\SocialEntity\MediaAttachments; use App\SocialEntity\Mention; use App\SocialEntity\Notification; use App\SocialEntity\Poll; use App\SocialEntity\PollOption; +use App\SocialEntity\Polls; use App\SocialEntity\Status; +use App\SocialEntity\Statuses; use App\SocialEntity\Tag; use CURLFile; use DateTime; @@ -433,7 +438,7 @@ class Mastodon_api } $params['body'] = $parameters; $url = $this->mastodon_url . $url; - + echo $url; return $this->get_content_remote($url, $params); } @@ -747,22 +752,6 @@ class Mastodon_api return $this->_post('/api/v1/follows', array('uri' => $uri)); } - /** - * instance - * - * Getting instance information - * - * @return array $response - * string $response['uri'] - * string $response['title'] - * string $response['description'] - * string $response['email'] - */ - public function instance(): array - { - return $this->_get('/api/v1/instance'); - } - /** * mutes * @@ -1100,6 +1089,18 @@ class Mastodon_api } + /** + * scheduled_statuses + * + * + * @return array $response + */ + public function get_instance(): array + { + return $this->_get('/api/v1/instance'); + } + + /** * scheduled_statuses * @@ -1280,6 +1281,46 @@ class Mastodon_api return $notification; } + /** + * get instance configuration from API reply + * @param $instantParams array + * @return Instance + */ + public function getInstanceConfiguration(array $instantParams): Instance + { + $Instance = new Instance(); + $Configuration = new Configuration(); + $Statuses = new Statuses(); + $MediaAttachments = new MediaAttachments(); + $Polls = new Polls(); + if(isset($instantParams['configuration'])) { + //Dealing with statuses configuration + if(isset($instantParams['configuration']['statuses'])) { + $Statuses->setMaxCharacters($instantParams['configuration']['statuses']['max_characters']); + $Statuses->setMaxMediaAttachments($instantParams['configuration']['statuses']['max_media_attachments']); + $Statuses->setCharactersReservedPerUrl($instantParams['configuration']['statuses']['characters_reserved_per_url']); + } + if(isset($instantParams['configuration']['media_attachments'])) { + $MediaAttachments->setSupportedMimeTypes($instantParams['configuration']['media_attachments']['supported_mime_types']); + $MediaAttachments->setImageSizeLimit($instantParams['configuration']['media_attachments']['image_size_limit']); + $MediaAttachments->setImageMatrixLimit($instantParams['configuration']['media_attachments']['image_matrix_limit']); + $MediaAttachments->setVideoSizeLimit($instantParams['configuration']['media_attachments']['video_size_limit']); + $MediaAttachments->setVideoFrameRateLimit($instantParams['configuration']['media_attachments']['video_frame_rate_limit']); + $MediaAttachments->setVideoMatrixLimit($instantParams['configuration']['media_attachments']['video_matrix_limit']); + } + if(isset($instantParams['configuration']['polls'])) { + $Polls->setMaxOptions($instantParams['configuration']['polls']['max_options']); + $Polls->setMaxCharactersPerOption($instantParams['configuration']['polls']['max_characters_per_option']); + $Polls->setMinExpiration($instantParams['configuration']['polls']['min_expiration']); + $Polls->setMaxExpiration($instantParams['configuration']['polls']['max_expiration']); + } + } + $Configuration->setStatuses($Statuses); + $Configuration->setMediaAttachments($MediaAttachments); + $Configuration->setPolls($Polls); + $Instance->setConfiguration($Configuration); + return $Instance; + } /** * getSingleAccount Hydrate a MastodonAccount from API reply * @param $accountParams array diff --git a/src/SocialEntity/Instance.php b/src/SocialEntity/Instance.php new file mode 100644 index 0000000..ef743c6 --- /dev/null +++ b/src/SocialEntity/Instance.php @@ -0,0 +1,211 @@ +max_characters; + } + + public function setMaxCharacters(int $max_characters): void + { + $this->max_characters = $max_characters; + } + + public function getMaxMediaAttachments(): int + { + return $this->max_media_attachments; + } + + public function setMaxMediaAttachments(int $max_media_attachments): void + { + $this->max_media_attachments = $max_media_attachments; + } + + public function getCharactersReservedPerUrl(): int + { + return $this->characters_reserved_per_url; + } + + public function setCharactersReservedPerUrl(int $characters_reserved_per_url): void + { + $this->characters_reserved_per_url = $characters_reserved_per_url; + } +} + +class MediaAttachments { + private array $supported_mime_types = ["image/jpeg","image/png","image/gif","image/heic","image/heif","image/webp","image/avif","video/webm","video/mp4","video/quicktime","video/ogg","audio/wave","audio/wav","audio/x-wav","audio/x-pn-wave","audio/vnd.wave","audio/ogg","audio/vorbis","audio/mpeg","audio/mp3","audio/webm","audio/flac","audio/aac","audio/m4a","audio/x-m4a","audio/mp4","audio/3gpp","video/x-ms-asf"]; + private int $image_size_limit = 16777216; + private int $image_matrix_limit = 33177600; + private int $video_size_limit = 103809024; + private int $video_frame_rate_limit = 120; + private int $video_matrix_limit = 8294400; + public function getSupportedMimeTypes(): array + { + return $this->supported_mime_types; + } + + public function setSupportedMimeTypes(array $supported_mime_types): void + { + $this->supported_mime_types = $supported_mime_types; + } + + public function getImageSizeLimit(): int + { + return $this->image_size_limit; + } + + public function setImageSizeLimit(int $image_size_limit): void + { + $this->image_size_limit = $image_size_limit; + } + + public function getImageMatrixLimit(): int + { + return $this->image_matrix_limit; + } + + public function setImageMatrixLimit(int $image_matrix_limit): void + { + $this->image_matrix_limit = $image_matrix_limit; + } + + public function getVideoSizeLimit(): int + { + return $this->video_size_limit; + } + + public function setVideoSizeLimit(int $video_size_limit): void + { + $this->video_size_limit = $video_size_limit; + } + + public function getVideoFrameRateLimit(): int + { + return $this->video_frame_rate_limit; + } + + public function setVideoFrameRateLimit(int $video_frame_rate_limit): void + { + $this->video_frame_rate_limit = $video_frame_rate_limit; + } + + public function getVideoMatrixLimit(): int + { + return $this->video_matrix_limit; + } + + public function setVideoMatrixLimit(int $video_matrix_limit): void + { + $this->video_matrix_limit = $video_matrix_limit; + } +} + + +class Polls { + private int $max_options = 4; + private int $max_characters_per_option = 50; + private int $min_expiration = 300; + private int $max_expiration = 2629746; + + public function getMaxOptions(): int + { + return $this->max_options; + } + + public function setMaxOptions(int $max_options): void + { + $this->max_options = $max_options; + } + + public function getMaxCharactersPerOption(): int + { + return $this->max_characters_per_option; + } + + public function setMaxCharactersPerOption(int $max_characters_per_option): void + { + $this->max_characters_per_option = $max_characters_per_option; + } + + public function getMinExpiration(): int + { + return $this->min_expiration; + } + + public function setMinExpiration(int $min_expiration): void + { + $this->min_expiration = $min_expiration; + } + + public function getMaxExpiration(): int + { + return $this->max_expiration; + } + + public function setMaxExpiration(int $max_expiration): void + { + $this->max_expiration = $max_expiration; + } + +} + +class Configuration { + private Statuses $statuses; + private MediaAttachments $mediaAttachments; + + public function getStatuses(): Statuses + { + return $this->statuses; + } + + public function setStatuses(Statuses $statuses): void + { + $this->statuses = $statuses; + } + + public function getMediaAttachments(): MediaAttachments + { + return $this->mediaAttachments; + } + + public function setMediaAttachments(MediaAttachments $mediaAttachments): void + { + $this->mediaAttachments = $mediaAttachments; + } + + public function getPolls(): Polls + { + return $this->polls; + } + + public function setPolls(Polls $polls): void + { + $this->polls = $polls; + } + private Polls $polls; + +} + + +class Instance +{ + private Configuration $configuration; + + public function getConfiguration(): Configuration + { + return $this->configuration; + } + + public function setConfiguration(Configuration $configuration): void + { + $this->configuration = $configuration; + } + +} + + diff --git a/templates/fediplan/schedule.html.twig b/templates/fediplan/schedule.html.twig index 45db44b..fcd1498 100644 --- a/templates/fediplan/schedule.html.twig +++ b/templates/fediplan/schedule.html.twig @@ -3,6 +3,7 @@ {% block title %}{{ 'common.schedule'|trans }}{% endblock %} {% block content %} + {% set instanceConfiguration = app.session.get("instance").getConfiguration() %} {% include 'nav.html.twig' %}

Schedule for {{ app.user.avatar }} {{ convertAccountEmoji(app.user, app.user.displayName) | raw }} (@{{ app.user.acct}}@{{ instance }})

@@ -56,6 +57,7 @@
  0 +  /{{ instanceConfiguration.statuses.maxCharacters }}
@@ -505,6 +507,10 @@ var $newFormLi = $('
  • ').append(newForm); $newLinkLi.before($newFormLi); addOptionFormDeleteLink($newFormLi); + var optionsCount = $collectionHolder.find('input').length; + if(optionsCount >= {{ app.session.get("instance").getConfiguration().polls.maxOptions }}) { + $addTagButton.hide(); + } } function addOptionFormDeleteLink($tagFormLi) { @@ -512,6 +518,10 @@ $tagFormLi.append($removeFormButton); $removeFormButton.on('click', function(e) { $tagFormLi.remove(); + var optionsCount = $collectionHolder.find('input').length; + if(optionsCount < {{ app.session.get("instance").getConfiguration().polls.maxOptions }}) { + $addTagButton.show(); + } }); }