Improved: Sharing/Integration configuration (#4269)

* stick plus button to select list

* HTML improved very much

* drag and drop improved

* add URL button

* fix remove button behavior

* prepare for PR#4238

* improve length of inputs

* First draft of documentation of the sharing services

* new config option: depricated

* i18n for depricated text

* Doc: Blogotext depricated to 2023

* dropdown menu with config link and depricated sign

* Update entry_bottom.phtml

* Update 08_sharing_services.md

* Update template.rtl.css

* Typo Deprecated/Depricated

* typo

* updated the documentation comment

* Update shares.php

* Update app/i18n/fr/conf.php

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

* Update p/scripts/draggable.js

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

* Update p/scripts/draggable.js

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>

* Documentation: services from #4270

Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
This commit is contained in:
maTh
2022-03-15 22:58:30 +01:00
committed by GitHub
parent bdf7e4d29d
commit be5848fd4f
28 changed files with 203 additions and 60 deletions

View File

@@ -20,12 +20,13 @@ class FreshRSS_Share {
return;
}
$isDeprecated = isset($share_options['deprecated']) ? $share_options['deprecated'] : false;
$help_url = isset($share_options['help']) ? $share_options['help'] : '';
$field = isset($share_options['field']) ? $share_options['field'] : null;
self::$list_sharing[$type] = new FreshRSS_Share(
$type, $share_options['url'], $share_options['transform'],
$share_options['form'], $help_url, $share_options['method'],
$field
$field, $isDeprecated
);
}
@@ -83,6 +84,7 @@ class FreshRSS_Share {
private $id = null;
private $title = null;
private $link = null;
private $isDeprecated = false;
private $method = 'GET';
private $field;
@@ -97,11 +99,12 @@ class FreshRSS_Share {
* @param string $help_url is an optional url to give help on this option.
* @param string $method defines the sharing method (GET or POST)
*/
private function __construct($type, $url_transform, $transform, $form_type, $help_url, $method, $field) {
private function __construct($type, $url_transform, $transform, $form_type, $help_url, $method, $field, $isDeprecated = false) {
$this->type = $type;
$this->name = _t('gen.share.' . $type);
$this->url_transform = $url_transform;
$this->help_url = $help_url;
$this->isDeprecated = $isDeprecated;
if (!is_array($transform)) {
$transform = array();
@@ -196,6 +199,13 @@ class FreshRSS_Share {
return $this->base_url;
}
/**
* Return the deprecated status of the share option.
*/
public function isDeprecated() {
return $this->isDeprecated;
}
/**
* Return the current url by merging url_transform and base_url.
*/

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Sdílení',
'add' => 'Přidat metodu sdílení',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'E-mail',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Teilen',
'add' => 'Füge eine Teilen-Dienst hinzu',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'Dieser Dienst ist veraltet und wir in einer <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">zukünftigen FreshRSS-Version</a> entfernt.',
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'E-Mail',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Sharing', // IGNORE
'add' => 'Add a sharing method', // IGNORE
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'Email', // IGNORE
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Sharing',
'add' => 'Add a sharing method',
'blogotext' => 'Blogotext',
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*',
'email' => 'Email',
'facebook' => 'Facebook',

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Compartir',
'add' => 'Agregar un método de uso compartido',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'Email', // TODO
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Partage',
'add' => 'Ajouter une méthode de partage',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'Ce service est obsolète et sera supprimé dans une <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Voir la documentation" target="_blank">prochaine version de FreshRSS</a>.',
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'Courriel',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'שיתוף',
'add' => 'Add a sharing method', // TODO
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'דואר אלקטרוני',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Condivisione',
'add' => 'Add a sharing method', // TODO
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'Email', // TODO
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => '共有',
'add' => '共有方法を追加する',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'Eメール',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => '공유',
'add' => '공유 방법 추가',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => '메일',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Delen',
'add' => 'Deelmethode toevoegen',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'Email', // IGNORE
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Partatge',
'add' => 'Ajustar un metòde de partatge',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'Corrièl',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Podawanie dalej',
'add' => 'Dodaj sposób na podanie dalej wiadomości',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'E-mail',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Compartilhando',
'add' => 'Adicionar um método de compartilhamento',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'E-mail',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Поделиться',
'add' => 'Добавить способ поделиться',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'Электронная почта',
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Zdieľanie',
'add' => 'Pridať spôsob zdieľania',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'E-mail', // IGNORE
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => 'Paylaşım',
'add' => 'Bir paylaşım türü ekle',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => 'Email', // IGNORE
'facebook' => 'Facebook', // IGNORE

View File

@@ -194,6 +194,7 @@ return array(
'_' => '分享',
'add' => '添加分享方式',
'blogotext' => 'Blogotext', // IGNORE
'deprecated' => 'This service is deprecated and will be removed from FreshRSS in a <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.md" title="Open documentation for more information" target="_blank">future release</a>.', // TODO
'diaspora' => 'Diaspora*', // IGNORE
'email' => '邮箱', // IGNORE
'facebook' => '脸书', // IGNORE

View File

@@ -7,23 +7,27 @@
*
* For each share there is different configuration options. Here is the description
* of those options:
* - url is a mandatory option. It is a string representing the share URL. It
* - 'deprecated' (optional) is a boolean. Default: 'false'.
* 'true', if the sharing service is planned to remove in the future.
* Add more information into the documentation center.
* - 'url' is a mandatory option. It is a string representing the share URL. It
* supports 4 different placeholders for custom data. The ~URL~ placeholder
* represents the URL of the system used to share, it is configured by the
* user. The ~LINK~ placeholder represents the link of the shared article.
* The ~TITLE~ placeholder represents the title of the shared article. The
* ~ID~ placeholder represents the id of the shared article (only useful
* for internal use)
* - transform is an array of transformation to apply on links and titles
* - help is a URL to a help page (mandatory for form = 'advanced')
* - form is the type of form to display during configuration. Its either
* - 'transform' is an array of transformation to apply on links and titles
* - 'help' is a URL to a help page (mandatory for form = 'advanced')
* - 'form' is the type of form to display during configuration. Its either
* 'simple' or 'advanced'. 'simple' is used when only the name is configurable,
* 'advanced' is used when the name and the location are configurable.
* - method is the HTTP method (POST or GET) used to share a link.
* - 'method' is the HTTP method (POST or GET) used to share a link.
*/
return array(
'blogotext' => array(
'deprecated' => true,
'url' => '~URL~/admin/links.php?url=~LINK~',
'transform' => array(),
'help' => 'http://lehollandaisvolant.net/blogotext/fr/',

View File

@@ -11,21 +11,28 @@
<h1><?= _t('conf.sharing') ?></h1>
<form method="post" action="<?= _url('configure', 'integration') ?>"
data-simple='<div class="form-group" id="group-share-##key##"><label class="group-name">##label##</label><div class="group-controls"><div class="stick">
<input type="text" id="share_##key##_name" name="share[##key##][name]" class="extend" value="##label##" placeholder="<?= _t('conf.sharing.share_name') ?>" size="64" />
<input type="url" id="share_##key##_url" name="share[##key##][url]" class="extend" value="" placeholder="<?= _t('gen.short.not_applicable') ?>" size="64" disabled="disabled" />
<a href="#" class="remove btn btn-attention"><?= _i('close') ?></a></div>
<input type="hidden" id="share_##key##_type" name="share[##key##][type]" value="##type##" /></div></div>'
data-advanced='<div class="form-group" id="group-share-##key##"><label class="group-name">##label##</label><div class="group-controls">
data-simple='<formgroup><legend>##label##</legend>
<input type="hidden" id="share_##key##_type" name="share[##key##][type]" value="##type##" />
<div class="form-group" id="group-share-##key##">
<label class="group-name" for="share_##key##_name"><?= _t('conf.sharing.share_name') ?></label><div class="group-controls">
<input type="text" id="share_##key##_name" name="share[##key##][name]" value="##label##" />
</div>
</div></formgroup>'
data-advanced='<formgroup class="group-share"><legend>##label##</legend>
<input type="hidden" id="share_##key##_type" name="share[##key##][type]" value="##type##" />
<input type="hidden" id="share_##key##_method" name="share[##key##][method]" value="##method##" />
<input type="hidden" id="share_##key##_field" name="share[##key##][field]" value="##field##" />
<div class="stick">
<input type="text" id="share_##key##_name" name="share[##key##][name]" class="extend" value="" placeholder="<?= _t('conf.sharing.share_name') ?>" size="64" />
<input type="url" id="share_##key##_url" name="share[##key##][url]" class="extend" value="" placeholder="<?= _t('conf.sharing.share_url') ?>" size="64" />
<a href="#" class="remove btn btn-attention" title="<?= _t('conf.sharing.remove') ?>"><?= _i('close') ?></a></div>
<a target="_blank" rel="noreferrer" class="btn" title="<?= _t('conf.sharing.more_information') ?>" href="##help##"><?= _i('help') ?></a>
</div></div>' class="draggableList">
<div class="form-group" id="group-share-##key##"><label class="group-name" for="share_##key##_name"><?= _t('conf.sharing.share_name') ?></label><div class="group-controls">
<input type="text" id="share_##key##_name" name="share[##key##][name]" value="" />
</div>
<div class="form-group" id="group-share-##key##"><label class="group-name" for="share_##key##_url"><?= _t('conf.sharing.share_url') ?></label><div class="group-controls">
<input type="url" id="share_##key##_url" name="share[##key##][url]" class="long" value="" required />
<p class="help"><?= _i('help') ?> <a href="##help##" target="_blank" rel="noreferrer"><?= _t('conf.sharing.more_information') ?></a></p>
</div><div class="form-group">
<div class="group-controls">
<button type="button" class="remove btn btn-attention" title="<?= _t('conf.sharing.remove') ?>"><?= _t('gen.action.remove') ?></button>
</div>
</div></formgroup>' class="draggableList">
<input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
<?php
@@ -33,46 +40,75 @@
$share = FreshRSS_Share::get($share_options['type']);
$share->update($share_options);
?>
<div class="form-group group-share" id="group-share-<?= $key ?>" draggable="true">
<label class="group-name">
<?= $share->name(true) ?>
<formgroup class="group-share dragbox" id="group-share-<?= $key ?>">
<legend draggable="true"><?= $share->name(true) ?></legend>
<input type="hidden" id="share_<?= $key ?>_type" name="share[<?= $key ?>][type]" value="<?= $share->type() ?>" />
<input type="hidden" id="share_<?= $key ?>_method" name="share[<?= $key ?>][method]" value="<?= $share->method() ?>" />
<input type="hidden" id="share_<?= $key ?>_field" name="share[<?= $key ?>][field]" value="<?= $share->field() ?>" />
<?php if ($share->isDeprecated()) { ?>
<div class="prompt alert alert-warn">
<p><?= _t('conf.sharing.deprecated') ?></p>
</div>
<?php } ?>
<div class="form-group">
<label class="group-name" for="share_<?= $key ?>_name">
<?= _t('conf.sharing.share_name') ?>
</label>
<div class="group-controls">
<input type='hidden' id='share_<?= $key ?>_type' name="share[<?= $key ?>][type]" value='<?= $share->type() ?>' />
<input type='hidden' id='share_<?= $key ?>_method' name="share[<?= $key ?>][method]" value='<?= $share->method() ?>' />
<input type='hidden' id='share_<?= $key ?>_field' name="share[<?= $key ?>][field]" value='<?= $share->field() ?>' />
<div class="stick">
<input type="text" id="share_<?= $key ?>_name" name="share[<?= $key ?>][name]" class="extend" value="<?= $share->name() ?>"
placeholder="<?= _t('conf.sharing.share_name') ?>" size="64" data-leave-validation="<?= $share->name() ?>"/>
<?php if ($share->formType() === 'advanced') { ?>
<input type="url" id="share_<?= $key ?>_url" name="share[<?= $key ?>][url]" class="extend" value="<?= $share->baseUrl() ?>"
placeholder="<?= _t('conf.sharing.share_url') ?>" size="64" data-leave-validation="<?= $share->baseUrl() ?>"/>
<?php } else { ?>
<input type="url" id="share_<?= $key ?>_url" name="share[<?= $key ?>][url]" class="extend" value="<?= $share->baseUrl() ?>"
placeholder="<?= _t('gen.short.not_applicable') ?>" size="64" disabled="disabled" />
<?php } ?>
<a href='#' class='remove btn btn-attention' title="<?= _t('conf.sharing.remove') ?>"><?= _i('close') ?></a>
</div>
<?php if ($share->formType() === 'advanced') { ?>
<a target="_blank" rel="noreferrer" class="btn" title="<?= _t('conf.sharing.more_information') ?>" href="<?= $share->help() ?>"><?= _i('help') ?></a>
<?php } ?>
<input type="text" id="share_<?= $key ?>_name" name="share[<?= $key ?>][name]" value="<?= $share->name() ?>"
data-leave-validation="<?= $share->name() ?>" />
</div>
</div>
<div class="form-group">
<?php if ($share->formType() === 'advanced') { ?>
<label class="group-name" for="share_<?= $key ?>_url">
<?= _t('conf.sharing.share_url') ?>
</label>
<div class="group-controls">
<div class="stick">
<input type="url" id="share_<?= $key ?>_url" name="share[<?= $key ?>][url]" class="long" value="<?= $share->baseUrl() ?>"
data-leave-validation="<?= $share->baseUrl() ?>" required />
<a class="btn open-url" target="_blank" rel="noreferrer" href="<?= $share->baseUrl() ?>" title="<?= _t('gen.action.see_url') ?>" data-input="share_<?= $key ?>_url"><?= _i('link') ?></a>
</div>
<p class="help"><?= _i('help') ?> <a href="<?= $share->help() ?>" target="_blank" rel="noreferrer"><?= _t('conf.sharing.more_information') ?></a></p>
</div>
<?php } ?>
</div>
<div class="form-group">
<div class="group-controls">
<button type="button" class="remove btn btn-attention" title="<?= _t('conf.sharing.remove') ?>"><?= _t('gen.action.remove') ?></button>
</div>
</div>
</formgroup>
<?php } ?>
<div class="form-group">
<div class="group-controls">
<select>
<?php foreach (FreshRSS_Share::enum() as $share) { ?>
<option value='<?= $share->type() ?>' data-form='<?= $share->formType() ?>' data-help='<?= $share->help() ?>'
data-method='<?= $share->method() ?>' data-field='<?= $share->field() ?>'>
<?= $share->name(true) ?>
</option>
<?php } ?>
</select>
<a href='#' class='share add btn' title="<?= _t('conf.sharing.add') ?>"><?= _i('add') ?></a>
<formgroup>
<legend>
<?= _t('conf.sharing.add') ?>
</legend>
<div class="form-group">
<div class="group-controls">
<div class="stick">
<select>
<?php foreach (FreshRSS_Share::enum() as $share) { ?>
<option value='<?= $share->type() ?>' data-form='<?= $share->formType() ?>' data-help='<?= $share->help() ?>'
data-method='<?= $share->method() ?>' data-field='<?= $share->field() ?>'>
<?= $share->name(true) ?>
</option>
<?php } ?>
</select>
<a href='#' class='share add btn' title="<?= _t('conf.sharing.add') ?>"><?= _i('add') ?></a>
</div>
</div>
</div>
</div>
</formgroup>
<div class="form-group form-actions">
<div class="group-controls">

View File

@@ -80,7 +80,8 @@
</a>
<ul class="dropdown-menu">
<li class="dropdown-close"><a href="#close"></a></li><?php
<li class="dropdown-close"><a href="#close"></a></li>
<li class="dropdown-header"><?= _t('index.share') ?> <a href="<?= _url('configure', 'integration') ?>"><?= _i('configure') ?></a></li><?php
$id = $this->entry->id();
$link = $this->entry->link();
$title = $this->entry->title() . ' · ' . $this->feed->name();
@@ -89,11 +90,12 @@
if ($share === null) {
continue;
}
$cssClass = $share->isDeprecated() ? ' error' : '';
$share_options['id'] = $id;
$share_options['link'] = $link;
$share_options['title'] = $title;
$share->update($share_options);
?><li class="item share">
?><li class="item share<?= $cssClass ?>">
<?php if ('GET' === $share->method()) {?>
<a target="_blank" rel="noreferrer" href="<?= $share->url() ?>" data-type="<?= $share->type() ?>"><?= $share->name() ?></a>
<?php } else {?>

View File

@@ -18,6 +18,7 @@ FreshRSS has a lot of features including:
* The application is "responsive," which means it adapts to small screens so you can bring articles in your pocket
* Self-hosted: the code is free (under AGPL3 licence), so you can host your own instance of FreshRSS
* Multi-user, so you can also host for your friends and family
* share article links with a bunch of services
* And a lot more!
## Manual Chapters

View File

@@ -0,0 +1,50 @@
# Sharing Services
FreshRSS has the option to share links with a bunch of services.
## Available Services: Simple Sharing
| Service | Short description | Notes |
|:--------------|:-------------------------------------------------------|:--------------------------------------------------------------|
| Clipboard | Copy article link into the operation system clipboard | |
| Email | Open the email app to send the article link | |
| Print | Open browser's print dialog to print out the article | |
## Available Services: Hosted Services
| Service | Short description | Links | Notes |
|:------------------|:-----------------------------------------------------|:-------------------------------------------------|:--------------------------------------------------------------|
| Blogotext | A little more than a lightweight SQLite Blog-Engine. | [GitHub](https://github.com/BlogoText/blogotext) | Deprecated since FreshRSS V1.20.0 (2022). Will be deleted in 2023 (scheduled to FreshRSS V1.22.0) |
| Diaspora* | The online social world where you are in control | [Website](https://diasporafoundation.org/), [Wikipedia](https://en.wikipedia.org/wiki/Diaspora_(social_network)) | |
| Facebook | Worldwide social network (by Meta Platforms) | [Website](https://facebook.com), [Wikipedia](https://en.wikipedia.org/wiki/Facebook)
| GNU social | Social communication software for both public and private communications | [Website](https://gnu.io/social/) | |
| Journal du hacker | Le Journal du hacker s'inspire directement du site anglophone Hacker News | [Website](https://www.journalduhacker.net/) |
| Known based sites | Its robust open source framework can be used to build fully-fledged community sites, or a blog for a single user. | [Website](https://withknown.com/) | |
| Lemmy | Selfhosted social link aggregation and discussion platform | [Website](https://join-lemmy.org/) | |
| LinkedIn | Business and employment-oriented online service | [Website](https://www.linkedin.com/), [Wikipedia](https://en.wikipedia.org/wiki/LinkedIn)| |
| Mastodon | Self-hosted social networking & microblogging services | [Website](https://joinmastodon.org/), [Wikipedia](https://en.wikipedia.org/wiki/Mastodon_(software)) | |
| Movim | A powerful web frontend for XMPP | [Website](https://movim.eu/) | |
| Pinboard | Social Bookmarking for Introverts | [Website](https://pinboard.in/) | |
| Pinterest | Is an image sharing and social media service designed to enable saving and discovery of information| [Website](https://pinterest.com/), [Wikipedia](https://en.wikipedia.org/wiki/Pinterest) | |
| Pocket | Social bookmarking (previous "Read it Later", owned by Mozilla) | [Website](https://getpocket.com), [Wikipedia](https://en.wikipedia.org/wiki/Pocket_(service)) | |
| Raindrop.io | All-in-one bookmark manager | [Website](https://raindrop.io/)| |
| Reddit | A network of communities where people can dive into their interests, hobbies and passions| [Website](https://www.reddit.com/), [Wikipedia](https://en.wikipedia.org/wiki/Reddit)| |
| Shaarli | Self-hosted minimalist bookmark manager and link sharing service | [Website](https://shaarli.readthedocs.io/) | |
| Twitter | Microblogging social network | [Website](https://twitter.com), [Wikipedia](https://de.wikipedia.org/wiki/Twitter) | |
| wallabag | Save and classify articles. Read them later. Freely | [Website](https://www.wallabag.org) | Compatible to version 1 and 2
| Whatsapp | Instant messaging and voice-over-IP service owned by Meta Platforms| [Website](https://www.whatsapp.com), [Wikipedia](https://en.wikipedia.org/wiki/WhatsApp) | |
| XING | Career-oriented social networking site, operated by New Work SE | [Website](https://www.xing.com/), [Wikipedia](https://en.wikipedia.org/wiki/XING) | |
## Configuration
Select the needed sharing services in the configuration menu (Configuration / Sharing).
## Usage
Activate the sharing menu in configuration menu (Configuration / Display). It is only available for the bottom line.
The menu with the selected services is available in the footer of article.
## Add More Sharing Services
Please open a new issue on [GitHub](https://github.com/FreshRSS/FreshRSS/issues) and support us with information.

View File

@@ -27,6 +27,10 @@ const init_draggable_list = function () {
draggableList.addEventListener('dragstart', event => {
source = event.target.closest('[draggable="true"]');
const dragbox = source.closest('.dragbox');
if (dragbox) {
source = dragbox;
}
event.dataTransfer.setData('text/html', source.outerHTML);
event.dataTransfer.effectAllowed = 'move';
});
@@ -36,7 +40,11 @@ const init_draggable_list = function () {
return;
}
const draggableItem = event.target.closest('[draggable="true"]');
let draggableItem = event.target.closest('[draggable="true"]');
const dragbox = event.target.closest('.dragbox');
if (dragbox) {
draggableItem = dragbox;
}
if (null === draggableItem || source === draggableItem) {
return;
}
@@ -59,7 +67,11 @@ const init_draggable_list = function () {
return;
}
const draggableItem = event.target.closest('[draggable="true"]');
let draggableItem = event.target.closest('[draggable="true"]');
const dragbox = event.target.closest('.dragbox');
if (dragbox) {
draggableItem = dragbox;
}
if (null === draggableItem || source === draggableItem) {
return;
}

View File

@@ -21,7 +21,7 @@ const init_integration = function () {
newShare = newShare.replace(/##key##/g, shares);
newShare = newShare.replace(/##method##/g, shareType.getAttribute('data-method'));
newShare = newShare.replace(/##field##/g, shareType.getAttribute('data-field'));
event.target.closest('.form-group').insertAdjacentHTML('beforebegin', newShare);
event.target.closest('formgroup').insertAdjacentHTML('beforebegin', newShare);
shares++;
});
@@ -30,7 +30,7 @@ const init_integration = function () {
return;
}
const deleteButton = event.target.closest('a.remove');
const deleteButton = event.target.closest('.remove');
if (null === deleteButton || !deleteButton.closest) {
return;
}

View File

@@ -1530,8 +1530,9 @@ input:checked + .slide-container .properties {
text-align: center;
}
.item.share.error a::after,
.category .title.error::before {
content: "⚠ ";
content: " ⚠ ";
color: #bd362f;
}
@@ -1672,6 +1673,10 @@ input:checked + .slide-container .properties {
position: inherit;
}
.dropdown .dropdown-header {
line-height: 2;
}
.dropdown .dropdown-menu {
width: 94%;
border-radius: 0;

View File

@@ -1530,8 +1530,9 @@ input:checked + .slide-container .properties {
text-align: center;
}
.item.share.error a::after,
.category .title.error::before {
content: "⚠ ";
content: " ⚠ ";
color: #bd362f;
}
@@ -1672,6 +1673,10 @@ input:checked + .slide-container .properties {
position: inherit;
}
.dropdown .dropdown-header {
line-height: 2;
}
.dropdown .dropdown-menu {
width: 94%;
border-radius: 0;