فهرست منبع

add new mastodon plugin

Dele Olajide 2 سال پیش
والد
کامیت
a21fabe60b
6فایلهای تغییر یافته به همراه246 افزوده شده و 2 حذف شده
  1. 12 2
      index.html
  2. 185 0
      packages/mastodon/mastodon.js
  3. BIN
      packages/mastodon/mastodon.png
  4. 17 0
      packages/mastodon/package.json
  5. 32 0
      packages/mastodon/readme.md
  6. 0 0
      packages/mastodon/timeago.min.js

+ 12 - 2
index.html

@@ -55,6 +55,9 @@
     <script src="packages/galene/protocol.js"></script>	
     <script src="packages/galene/galene-socket.js"></script>
     <script src="packages/galene/galene.js"></script>	
+	
+	<script src="packages/mastodon/timeago.min.js"></script>		
+    <script src="packages/mastodon/mastodon.js"></script>		
 </head>
 <body class="reset">
     <div class="converse-content" style="display:none">
@@ -104,7 +107,14 @@
         auto_reconnect: true,
         discover_connection_methods: true,
 		galene_url: "https://conversejs.github.io/community-plugins/packages/galene",
-		galene_host: 'pade.chat',		
+		galene_host: 'pade.chat',	
+		mastodon: {
+			url: "https://toot.igniterealtime.org", 
+			toolbar: true,
+			limit: 25,	
+			check: 15,	
+			title: "Mastodon Feed"
+		},
         view_mode: 'fullscreen',
         loglevel: 'debug',
         whitelisted_plugins: [
@@ -123,7 +133,7 @@
 			"actions", 
 			"voicechat", 
 			"galene", 			
-			// "polls" 
+			"mastodon",
 			"adaptive-cards"
 		]
     };

+ 185 - 0
packages/mastodon/mastodon.js

@@ -0,0 +1,185 @@
+(function (root, factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(["converse"], factory);
+    } else {
+        factory(converse);
+    }
+}(this, function (converse) {
+    var mastodonInterval;
+    var Strophe, dayjs
+
+    converse.plugins.add("mastodon", {
+        'dependencies': [],
+
+        'initialize': function () {
+            _converse = this._converse;
+            Strophe = converse.env.Strophe;
+            dayjs = converse.env.dayjs;
+			
+            _converse.api.settings.update({
+				mastodon: {
+					url: "https://toot.igniterealtime.org", 
+					token: "",
+					toolbar: true,
+					limit: 25,	
+					check: 15,	
+					title: "Mastodon Feed"
+				}		
+            });			
+			
+            _converse.api.listen.on('beforeMessageBodyTransformed', function(text)
+            {					
+				if (text.trim().startsWith("MASTODON:")) {	
+					const strings = [text.substr(9)];
+					strings.raw = strings;								
+					text.addTemplateResult(0, text.length, html(strings));
+				}				
+            });
+			
+            _converse.api.listen.on('chatBoxViewInitialized', function (view)
+            {
+				var jid = view.model.get("jid");
+				var type = view.model.get("type");
+				console.debug("chatBoxViewInitialized", jid, type);
+
+				if (jid === "converse-mastodon@" + _converse.connection.domain)
+				{
+					if (_converse.api.settings.get("mastodon").toolbar) {
+						const textarea = view.querySelector('.chat-textarea')
+						if (textarea) textarea.setAttribute("disabled", "true");
+					} else {
+						view.querySelector('.bottom-panel').style.display = "none";
+					}
+					mastodonRefresh();
+				}					
+            });
+
+            _converse.api.listen.on('connected', function()
+            {
+                _converse.api.waitUntil('rosterContactsFetched').then(() => {
+
+					window.addEventListener("unload", function ()
+					{
+						console.debug("mastodon unloading all feed refreshing");
+
+						if (mastodonInterval) clearInterval(mastodonInterval);
+					});
+
+					var mastodonCheck = _converse.api.settings.get("mastodon").check * 60000;
+					mastodonInterval = setInterval(mastodonRefresh, mastodonCheck);	
+					
+					const jid = "converse-mastodon@" + _converse.connection.domain;
+					openChat(jid, _converse.api.settings.get("mastodon").title, ["Bots"]);	
+
+					setupTimer();
+                });
+            });
+
+            console.log("mastodon plugin is ready");
+        }
+    });	
+
+	function setupTimer() {	
+		setupTimeAgo();		
+		setTimeout(setupTimer, 10000);	
+	}
+
+	function setupTimeAgo() {
+		timeago.cancel();
+		const locale = navigator.language.replace('-', '_');
+		
+		const elements = document.querySelectorAll('.chat-msg__time');
+		
+		for (let i=0; i < elements.length; i++)
+		{
+			if (!elements[i].querySelector('.chat-msg__time_span')) {
+				const timestamp = elements[i].getAttribute('timestamp');	
+				const pretty_time = elements[i].innerHTML;				
+				const timeAgo = timeago.format(new Date(pretty_time));
+				elements[i].innerHTML = '<span class="chat-msg__time_span" title="' + pretty_time + '" datetime="' + timestamp + '">' + timeAgo + '</span>';
+			}
+		}
+		
+		timeago.render(document.querySelectorAll('.chat-msg__time_span'), locale);
+	}	
+
+	function mastodonRefresh()
+	{
+		mastodonFetch("/api/v1/timelines/public");
+		mastodonFetch("/api/v1/timelines/home");		
+	}
+	
+	async function mastodonFetch(path)
+	{
+		console.debug("mastodon mastodonRefresh", path);	
+
+		const token = _converse.api.settings.get("mastodon").token;				
+		const endpoint = _converse.api.settings.get("mastodon").url + path + "?limit=" + _converse.api.settings.get("mastodon").limit;
+		
+		const options = {method: "GET", headers: {"Authorization": (token ? "Bearer " + token : token), "Accept":"application/json", "Content-Type":"application/json"}};
+		const response = await fetch(endpoint, options);
+		const posts = await response.json();				
+						
+		posts.forEach(async function(json)
+		{	
+			console.debug("mastodon mastodonRefresh", path, json);			
+			
+			if ((!json.content || json.content == "") && json.reblog?.account) {
+				json = json.reblog;		
+			}
+			
+			const user = json.account.username + "@" + _converse.connection.domain;				
+			const time = dayjs(json.created_at).format('MMM DD YYYY HH:mm:ss');	
+			const msgId = json.id;
+			const title = json.account.display_name.trim() == "" ? json.account.username : json.account.display_name;
+			const avatar = json.account.avatar_static;	
+			const timeAgo = timeago.format(new Date(json.created_at));
+			const timeAgoSpan = "<span class=chat-msg__time_span title='" + time + "' datetime='" + json.created_at + "'>" + timeAgo + '</span>';
+			const header = "<img width=48 style='border-radius: var(--avatar-border-radius)' src='" + avatar + "'/><br/><b>" + title + '</b> - ' + timeAgoSpan + " - <a href='" + json.url + "'>Reply<br/>"			
+			
+			let footer = "";
+			let cardImage = "";
+
+			if (json.card) {
+				if (json.card.image) cardImage = '<img src="' + json.card.image + '"/>';				
+				footer = `<p>${cardImage}</p><p>${json.card.description}</p><p><a target=_blank href='${json.card.url}'>${json.card.title}</a></p>`
+			}
+			const from = "converse-mastodon@" + _converse.connection.domain;			
+			const body = 'MASTODON:' + header + json.content + footer;			
+			const attrs = {json, body, message: body, id: msgId, msgId, type: 'chat', from, time, is_unstyled: true};  
+			chatbox = await _converse.api.chats.get(from, {}, true);
+			await (chatbox === null || chatbox === void 0 ? void 0 : chatbox.queueMessage(attrs));						
+		})				
+	}
+	
+	function openChat(from, name, groups, closed) {
+		console.debug("openChat", from, name, groups, closed);
+		
+		if (_converse && _converse.roster)
+		{
+			if (!groups) groups = [];
+
+			if (!name)
+			{
+				name = from.split("@")[0];
+				if (name && name.indexOf("sms-") == 0) name = name.substring(4);
+			}
+
+			var contact = _converse.roster.findWhere({'jid': from});
+
+			if (!contact)
+			{
+			  _converse.roster.create({
+				'nickname': name,
+				'groups': groups,
+				'jid': from,
+				'subscription': 'both'
+			  }, {
+				sort: false
+			  });
+			}
+
+			if (!closed) _converse.api.chats.open(from, {'bring_to_foreground': true}, true);
+		}
+	}	
+}));

BIN
packages/mastodon/mastodon.png


+ 17 - 0
packages/mastodon/package.json

@@ -0,0 +1,17 @@
+{
+  "name": "@converse-plugins/mastodon",
+  "author": "Dele Olajide",
+  "license": "Apache 2.0",
+  "version": "0.0.1-alpha.0",
+  "keywords": [
+    "converse.js",
+    "plugin"
+  ],
+  "publishConfig": {
+    "access": "public"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/conversejs/community-plugins.git"
+  }
+}

+ 32 - 0
packages/mastodon/readme.md

@@ -0,0 +1,32 @@
+# Location plugin for converse.js
+
+<img src="https://github.com/conversejs/community-plugins/blob/master/packages/mastodon/mastodon.png?raw=true" />
+
+## Overview
+This plugin implements [XEP-XXXX](https://igniterealtime.github.io/openfire-pade-plugin/xep/mastodon-api-over-xmpp.html) - This specification defines a protocol extension for communicating in-band with a Mastodon API server over XMPP.
+
+## Install
+see https://m.conversejs.org/docs/html/plugin_development.html on how to install this plugin
+
+## Configure
+To configure, edit the converse settings and modify the mastodon object attributes. See index.html for an example
+
+```
+converse.initialize({
+    ....
+	mastodon: {
+		url: "https://toot.igniterealtime.org", 
+		token: "",
+		toolbar: true,
+		limit: 25,	
+		check: 15,	
+		title: "Mastodon Feed"
+	},
+    ....
+});
+```
+
+Default setting will use the public toot.igniterealtime.org service.
+
+## How to use
+Click on the arrow icon to publish your geo mastodon

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
packages/mastodon/timeago.min.js


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است