add sharing to telegram

This commit is contained in:
Georg Gadinger 2023-02-19 20:58:47 +01:00
parent 6b976e0f89
commit 4ee2b46b32
8 changed files with 152 additions and 25 deletions

View file

@ -5,6 +5,7 @@ require "cgi"
class Ajax::AnswerController < AjaxController
include SocialHelper::TwitterMethods
include SocialHelper::TumblrMethods
include SocialHelper::TelegramMethods
def create
params.require :id
@ -41,13 +42,7 @@ class Ajax::AnswerController < AjaxController
@response[:message] = t(".success")
@response[:success] = true
if current_user.sharing_enabled
@response[:sharing] = {
twitter: twitter_share_url(answer),
tumblr: tumblr_share_url(answer),
custom: CGI.escape(prepare_tweet(answer))
}
end
@response[:sharing] = sharing_hash(answer) if current_user.sharing_enabled
return if inbox
@ -74,4 +69,13 @@ class Ajax::AnswerController < AjaxController
@response[:message] = t(".success")
@response[:success] = true
end
private
def sharing_hash(answer) = {
twitter: twitter_share_url(answer),
tumblr: tumblr_share_url(answer),
telegram: telegram_share_url(answer),
custom: CGI.escape(prepare_tweet(answer)),
}
end

View file

@ -1,4 +1,7 @@
# frozen_string_literal: true
module SocialHelper
include SocialHelper::TwitterMethods
include SocialHelper::TumblrMethods
end
include SocialHelper::TelegramMethods
end

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
require "cgi"
module SocialHelper::TelegramMethods
include MarkdownHelper
def telegram_text(answer)
# using twitter_markdown here as it removes all formatting
"#{twitter_markdown answer.question.content}\n———\n#{twitter_markdown answer.content}"
end
def telegram_share_url(answer)
url = answer_url(
id: answer.id,
username: answer.user.screen_name,
host: APP_CONFIG["hostname"],
protocol: (APP_CONFIG["https"] ? :https : :http)
)
%(https://t.me/share/url?url=#{CGI.escape(url)}&text=#{CGI.escape(telegram_text(answer))})
end
end

View file

@ -1,10 +1,11 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['twitter', 'tumblr', 'custom'];
static targets = ['twitter', 'tumblr', 'telegram', 'custom'];
declare readonly twitterTarget: HTMLAnchorElement;
declare readonly tumblrTarget: HTMLAnchorElement;
declare readonly telegramTarget: HTMLAnchorElement;
declare readonly customTarget: HTMLAnchorElement;
declare readonly hasCustomTarget: boolean;
@ -20,6 +21,7 @@ export default class extends Controller {
if (this.autoCloseValue) {
this.twitterTarget.addEventListener('click', () => this.close());
this.tumblrTarget.addEventListener('click', () => this.close());
this.telegramTarget.addEventListener('click', () => this.close());
if (this.hasCustomTarget) {
this.customTarget.addEventListener('click', () => this.close());
@ -36,6 +38,7 @@ export default class extends Controller {
this.twitterTarget.href = this.configValue['twitter'];
this.tumblrTarget.href = this.configValue['tumblr'];
this.telegramTarget.href = this.configValue['telegram'];
if (this.hasCustomTarget) {
this.customTarget.href = `${this.customTarget.href}${this.configValue['custom']}`;

View file

@ -49,6 +49,9 @@
%a.btn.btn-primary{ href: "#", data: { inbox_sharing_target: "tumblr" }, target: "_blank" }
%i.fab.fa-tumblr.fa-fw
Tumblr
%a.btn.btn-primary{ href: "#", data: { inbox_sharing_target: "telegram" }, target: "_blank" }
%i.fab.fa-telegram.fa-fw
Telegram
- if current_user.sharing_custom_url.present?
%a.btn.btn-primary{ href: current_user.sharing_custom_url, data: { inbox_sharing_target: "custom" }, target: "_blank" }
= current_user.display_sharing_custom_url

View file

@ -13,7 +13,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
id:,
answer:,
share: shared_services&.to_json,
inbox:
inbox:,
}.compact
end
@ -42,7 +42,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
"success" => false,
# caught by rescue_from, so status is not peter_dinklage
"status" => "parameter_error",
"message" => anything
"message" => anything,
}
end
@ -70,13 +70,33 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => true,
"status" => "okay",
"message" => anything
"message" => anything,
}
end
include_examples "creates the answer"
it_behaves_like "fails when answer content is empty"
context "when the user has sharing enabled" do
before do
user.sharing_enabled = true
user.save
end
let(:expected_response) do
super().merge(
"sharing" => {
"twitter" => a_string_matching("https://twitter.com/"),
"tumblr" => a_string_matching("https://www.tumblr.com/"),
"telegram" => a_string_matching("https://t.me/"),
"custom" => a_string_matching(/Werfen\+Sie\+nicht\+l%C3%A4nger\+das\+Fenster\+zum\+Geld\+hinaus%21/),
}
)
end
include_examples "creates the answer"
end
end
context "when the inbox entry does not belong to the user" do
@ -85,7 +105,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => false,
"status" => "fail",
"message" => anything
"message" => anything,
}
end
@ -100,7 +120,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => true,
"status" => "okay",
"message" => anything
"message" => anything,
}
end
@ -129,13 +149,33 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
"success" => true,
"status" => "okay",
"message" => anything,
"render" => anything
"render" => anything,
}
end
include_examples "creates the answer"
it_behaves_like "fails when answer content is empty"
context "when the user has sharing enabled" do
before do
user.sharing_enabled = true
user.save
end
let(:expected_response) do
super().merge(
"sharing" => {
"twitter" => a_string_matching("https://twitter.com/"),
"tumblr" => a_string_matching("https://www.tumblr.com/"),
"telegram" => a_string_matching("https://t.me/"),
"custom" => a_string_matching(/Werfen\+Sie\+nicht\+l%C3%A4nger\+das\+Fenster\+zum\+Geld\+hinaus%21/),
}
)
end
include_examples "creates the answer"
end
end
context "when question asker does not allow strangers to answer (i.e. question was not in inbox)" do
@ -144,7 +184,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => false,
"status" => "privacy_stronk",
"message" => anything
"message" => anything,
}
end
@ -160,7 +200,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => false,
"status" => "answering_other_blocked_self",
"message" => I18n.t("errors.answering_other_blocked_self")
"message" => I18n.t("errors.answering_other_blocked_self"),
}
end
@ -176,7 +216,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => false,
"status" => "answering_self_blocked_other",
"message" => I18n.t("errors.answering_self_blocked_other")
"message" => I18n.t("errors.answering_self_blocked_other"),
}
end
@ -196,7 +236,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
"success" => false,
# caught by rescue_from, so status is not peter_dinklage
"status" => "parameter_error",
"message" => anything
"message" => anything,
}
end
@ -214,7 +254,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => false,
"status" => "err",
"message" => anything
"message" => anything,
}
end
@ -230,7 +270,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
let(:params) do
{
answer: answer_id
answer: answer_id,
}
end
@ -242,7 +282,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => true,
"status" => "okay",
"message" => anything
"message" => anything,
}
end
@ -259,7 +299,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => false,
"status" => "nopriv",
"message" => anything
"message" => anything,
}
end
@ -311,7 +351,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => false,
"status" => anything,
"message" => anything
"message" => anything,
}
end
@ -324,7 +364,7 @@ describe Ajax::AnswerController, :ajax_controller, type: :controller do
{
"success" => false,
"status" => "nopriv",
"message" => anything
"message" => anything,
}
end

View file

@ -0,0 +1,47 @@
# frozen_string_literal: true
require "rails_helper"
describe SocialHelper::TelegramMethods, type: :helper do
let(:user) { FactoryBot.create(:user) }
let(:answer) do
FactoryBot.create(
:answer,
user:,
content: "this is an answer\nwith multiple lines\nand **FORMATTING**",
question_content: "this is a question .... or is it?"
)
end
before do
stub_const("APP_CONFIG", {
"hostname" => "example.com",
"https" => true,
"items_per_page" => 5,
})
end
describe "#telegram_text" do
subject { telegram_text(answer) }
it "returns a proper text for sharing" do
expect(subject).to eq(<<~TEXT.strip)
this is a question .... or is it?
this is an answer
with multiple lines
and FORMATTING
TEXT
end
end
describe "#telegram_share_url" do
subject { telegram_share_url(answer) }
it "returns a proper share link" do
expect(subject).to eq(<<~URL.strip)
https://t.me/share/url?url=https%3A%2F%2Fexample.com%2F%40#{answer.user.screen_name}%2Fa%2F#{answer.id}&text=this+is+a+question+....+or+is+it%3F%0A%E2%80%94%E2%80%94%E2%80%94%0Athis+is+an+answer%0Awith+multiple+lines%0Aand+FORMATTING
URL
end
end
end

View file

@ -82,6 +82,10 @@ describe "inbox/_entry.html.haml", type: :view do
expect(rendered).to have_css(%(.inbox-entry__sharing.d-none))
end
it "has a link-button to share to telegram" do
expect(rendered).to have_css(%(.inbox-entry__sharing a.btn[data-inbox-sharing-target="telegram"]))
end
it "has a link-button to share to tumblr" do
expect(rendered).to have_css(%(.inbox-entry__sharing a.btn[data-inbox-sharing-target="tumblr"]))
end