Invitation
This commit is contained in:
parent
f2c86b68d9
commit
a7b9824f97
46
i/css/i.css
Normal file
46
i/css/i.css
Normal file
@ -0,0 +1,46 @@
|
||||
body {
|
||||
background: #f8f8f8;
|
||||
color: #000000;
|
||||
font-size: 1em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.5em;
|
||||
font-weight: 400;
|
||||
line-height: 1.1;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1b8250;
|
||||
}
|
||||
|
||||
li {
|
||||
padding-bottom: 0.75em;
|
||||
}
|
||||
|
||||
.btn:hover, .btn:focus, .btn.focus {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #43a047;
|
||||
color: #f2f2f2;
|
||||
}
|
||||
.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary {
|
||||
background: #388e3c;
|
||||
color: #000000;
|
||||
box-shadow: none;
|
||||
}
|
||||
.btn-primary:active, .btn-primary.active {
|
||||
background: #2e7d32;
|
||||
box-shadow: none;
|
||||
}
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
.hint {
|
||||
font-size: 0.9em;
|
||||
color: #444;
|
||||
}
|
66
i/css/styles.css
Normal file
66
i/css/styles.css
Normal file
@ -0,0 +1,66 @@
|
||||
/* Mostly cherrypicked from bootstrap https://getbootstrap.com/css/ */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
vertical-align: middle; text-transform: uppercase;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
transition: all .2s;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
white-space: nowrap;
|
||||
padding: 6px 16px;
|
||||
font-size: 13px;
|
||||
line-height: 1.846;
|
||||
border-radius: 3px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.btn:hover, .btn:focus, .btn.focus {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
textarea, textarea.form-control, input.form-control, input[type="text"], input[type="password"], input[type="email"], input[type="number"], .form-control[type="text"], .form-control[type="password"], .form-control[type="email"], .form-control[type="tel"] {
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: inset 0 -1px 0 #ddd;
|
||||
box-shadow: inset 0 -1px 0 #ddd;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 37px;
|
||||
line-height: 1.846;
|
||||
color: #666;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
|
||||
-webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
|
||||
}
|
||||
|
||||
input, button {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
letter-spacing: .1px;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover, a:focus {
|
||||
color: #165d16;
|
||||
text-decoration: underline;
|
||||
}
|
37
i/index.html
Normal file
37
i/index.html
Normal file
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<meta content="IE=edge" http-equiv="X-UA-Compatible">
|
||||
<meta content="width=device-width, initial-scale=1, user-scalable=0" name="viewport">
|
||||
<title></title>
|
||||
<link href="css/styles.css" rel="stylesheet">
|
||||
<link href="css/i.css" rel="stylesheet">
|
||||
<style>
|
||||
.main {
|
||||
padding-top: 0px;
|
||||
max-width: 600px;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<noscript><h3>Вам нужен JavaScript для принятия этого приглашения.</h3></noscript>
|
||||
<h3 class="text-center" id="heading"></h3>
|
||||
<p class="text-center"><a class="btn btn-primary" id="button" href=""></a></p>
|
||||
<input type="url" class="form-control text-center" id="url_in" readonly="readonly" value="">
|
||||
<p class="hint text-center" id="clients"></p>
|
||||
<p class="lead" id="recommend"></p>
|
||||
|
||||
<ul class="lead" id="client_list"></ul>
|
||||
|
||||
<p class="lead" id="checkfulllist"></p>
|
||||
<p class="hint" id="xmppis"></p>
|
||||
</div>
|
||||
<script src="js/i18n-text.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
|
||||
</body></html>
|
6
i/js/i18n-text.js
Normal file
6
i/js/i18n-text.js
Normal file
@ -0,0 +1,6 @@
|
||||
/*!
|
||||
i18n-text - v0.4.3 - 2014-08-14
|
||||
https://vogdb@bitbucket.org/vogdb/i18n-text.git
|
||||
Copyright (c) 2014 Sanin Aleksey aka vogdb; Licensed WTFPL
|
||||
*/
|
||||
!function(a){function b(a){return"[object Object]"===Object.prototype.toString.call(a)}function c(a,b){return a.replace(/{{([\w]+)}}/g,function(a,c){var d=b[c];return d?d:a})}function d(a,b){throw new Error(c(a,b))}function e(a){return-1!==a.indexOf("file://")}function f(a){return e(a)||e(window.location.href)&&a.indexOf(!1)}var g={parseAndEval:function(a,b){return a.replace(/{{([^{}]+#[^}]*(?:|.*#.*)+)}}/g,function(a,c){return g.eval(c,b)})},eval:function(a,b){for(var c=a.split("|"),e=c.length-1;e>=0;e--){var f=c[e].split("#"),i=f[0];if(g.isValidFormula(i)||d(h.error.INVALID_PLURAL,{plural:i}),g.evalFormula(i,b))return f[1]}return a},isValidFormula:function(a){return/[ \dn<>=*-+!?]+/g.test(a)},evalFormula:function(a,b){return new Function("n","return "+a)(b)}},h=function(a){this._loadedLocales={},this._currentLocale=null,this._msgPath=null,this._subscribers={},this._init(a)};h.prototype.getLocale=function(){return this._currentLocale},h.prototype.setLocale=function(a){this.hasLocale(a)?this._setLocale(a):(this.once(h.event.LOCALE_LOAD,function(b){b.error||b.locale!==a||this._setLocale(b.locale)}.bind(this)),this.loadLocale(a))},h.prototype._setLocale=function(a){this._currentLocale=a,this._fire(h.event.LOCALE_CHANGE,{locale:a})},h.prototype.hasLocale=function(a){return!!this._loadedLocales[a]},h.prototype.loadLocale=function(a,b){b=b||this._msgPath;var d=b+"/"+a+".json";h.loadFile({url:d,success:function(b){b.length>0?(this._loadedLocales[a]={},this._mergeKeys(JSON.parse(b),this._loadedLocales[a],""),this._fire(h.event.LOCALE_LOAD,{locale:a})):this._fire(h.event.LOCALE_LOAD,{error:c(h.error.EMPTY_MESSAGES,{file:d})})}.bind(this),error:function(a){this._fire(h.event.LOCALE_LOAD,{error:c(h.error.NO_MESSAGES,{file:d,error:a})})}.bind(this)})},h.prototype._mergeKeys=function(a,c,d){for(var e in a)if(b(a[e])){var f;f=d?d+h.KEY_SEPARATOR+e:e,this._mergeKeys(a[e],c,f)}else{var g;g=d?d+h.KEY_SEPARATOR+e:e,c[g]=a[e]}},h.prototype.text=function(a,e,f){arguments[1]&&!b(arguments[1])&&(f=arguments[1],e=void 0);var i=f||this.getLocale();i||d(h.error.NO_LOCALE_IS_SET),this.hasLocale(i)||this.loadLocale(i);var j=this._loadedLocales[i][a];return void 0===j&&d(h.error.INVALID_KEY,{key:a,locale:i}),e?(void 0!==e.n&&(j=g.parseAndEval(j,e.n)),c(j,e)):j},h.prototype.on=function(a,b){this._subscribers[a]||(this._subscribers[a]=[]),this._subscribers[a].push(b)},h.prototype._fire=function(a,b){if(this._subscribers[a])for(var c=this._subscribers[a],d=c.length-1;d>=0;d--)c[d].call(null,b)},h.prototype.off=function(a,b){if(this._subscribers[a]){if(b){var c=this._subscribers[a].indexOf(b);this._subscribers[a].splice(c,1)}b&&0!==this._subscribers.length||delete this._subscribers[a]}},h.prototype.once=function(a,b){this.on(a,function(c){this.off(a,b),b(c)}.bind(this))},h.prototype._init=function(a){a||d(h.error.NO_OPTS),a.path?this._msgPath=a.path:d(h.error.NO_PATH)},h.loadFile=function(a){var b=new XMLHttpRequest;b.open("GET",a.url),b.onreadystatechange=function(){4===b.readyState&&(200==b.status||f(a.url)&&b.responseText.length>0?a.success(b.responseText):a.error(b.responseText))},b.send(null)},h.error={NO_OPTS:"Options are not present",NO_PATH:"Options path is not present",NO_MESSAGES:"{{file}} is unreachable. Error {{error}}",EMPTY_MESSAGES:"{{file}} is empty",INVALID_KEY:"{{key}} key is not present in locale {{locale}}",NO_LOCALE_IS_SET:"Locale is not set.",INVALID_PLURAL:"Invalid plural form: {{plural}}"},h.event={LOCALE_LOAD:"localeload",LOCALE_CHANGE:"localechange"},h.KEY_SEPARATOR=".","function"==typeof define&&define.amd?define(function(){return h}):a.I18nText=h}("undefined"==typeof window?this:window);
|
121
i/js/main.js
Normal file
121
i/js/main.js
Normal file
@ -0,0 +1,121 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var initialized = false;
|
||||
var i18n;
|
||||
|
||||
// i18n key prefix for MUC ("muc.") or 1:1 chat ("chat.")
|
||||
var key_prefix;
|
||||
var display_data = null;
|
||||
|
||||
function show_clients(client_array) {
|
||||
var list = document.getElementById('client_list');
|
||||
for (var id = 0; id < client_array.length; id++) {
|
||||
var item = document.createElement('li');
|
||||
item.innerHTML = client_array[id];
|
||||
list.appendChild(item);
|
||||
}
|
||||
}
|
||||
|
||||
function load_clients(url) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', url);
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === 4) {
|
||||
if (request.status === 200 || (isLocalFileRequest(url) && request.responseText.length > 0)) {
|
||||
show_clients(JSON.parse(request.responseText));
|
||||
}
|
||||
}
|
||||
};
|
||||
request.send(null);
|
||||
}
|
||||
|
||||
function load_hash() {
|
||||
var muc = false;
|
||||
key_prefix = "chat.";
|
||||
var jid = window.location.search || window.location.hash;
|
||||
jid = decodeURIComponent(jid.substring(jid.indexOf('#') + 1, jid.length));
|
||||
|
||||
if (jid === "")
|
||||
jid = "decentralized@conference.moemoekyun.moe?join"
|
||||
|
||||
try {
|
||||
base_decoded = window.atob(jid);
|
||||
if (base_decoded.search('@') >= 0)
|
||||
jid = base_decoded;
|
||||
} catch (err) {
|
||||
// ignore error, JID wasn't base64 encoded
|
||||
}
|
||||
if (jid.search("\\?join") >= 0) {
|
||||
muc = true;
|
||||
key_prefix = "muc.";
|
||||
}
|
||||
|
||||
// TODO: proper error checking / display / Creation of invitations
|
||||
if (jid.search("@") <= 0) return {jid: jid, name: jid};
|
||||
|
||||
var name = jid.split("@")[0];
|
||||
name = name.charAt(0).toUpperCase() + name.slice(1);
|
||||
|
||||
return {jid: jid, name: name};
|
||||
}
|
||||
|
||||
function translate_ui() {
|
||||
// translation
|
||||
document.title = i18n.text(key_prefix + 'title', display_data);
|
||||
// MUC/chat specific
|
||||
['heading', 'button'].forEach(function(id) {
|
||||
document.getElementById(id).innerHTML = i18n.text(key_prefix + id, display_data);
|
||||
});
|
||||
// and agnostic
|
||||
['clients', 'recommend', 'checkfulllist', 'xmppis'].forEach(function(id) {
|
||||
document.getElementById(id).innerHTML = i18n.text(id, display_data);
|
||||
});
|
||||
}
|
||||
|
||||
function rehash() {
|
||||
display_data = load_hash();
|
||||
document.getElementById('button').href = "xmpp:" + display_data.jid;
|
||||
document.getElementById('url_in').value = "xmpp:" + display_data.jid;
|
||||
translate_ui();
|
||||
}
|
||||
|
||||
function load_done() {
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
|
||||
// load i18n and perform translation
|
||||
i18n = new I18nText({path: 'lang'});
|
||||
i18n.once(I18nText.event.LOCALE_CHANGE, function (data) {
|
||||
rehash();
|
||||
});
|
||||
i18n.setLocale('ru');
|
||||
|
||||
// functionality
|
||||
if (navigator.userAgent.indexOf("Android") >= 0) {
|
||||
load_clients("json/clients_Android.json")
|
||||
}
|
||||
else if (navigator.userAgent.indexOf("Linux") >= 0) {
|
||||
load_clients("json/clients_Linux.json")
|
||||
}
|
||||
else if (navigator.userAgent.indexOf("iPhone") >= 0) {
|
||||
load_clients("json/clients_iOS.json")
|
||||
}
|
||||
else {
|
||||
load_clients("json/clients_Windows.json")
|
||||
}
|
||||
|
||||
window.addEventListener("hashchange", rehash, false);
|
||||
document.getElementById("url_in").addEventListener("focus", function(event) {
|
||||
event.target.select();
|
||||
});
|
||||
}
|
||||
|
||||
// Wait for the DOM to be ready
|
||||
document.addEventListener('DOMContentLoaded', load_done, false);
|
||||
document.onreadystatechange = function() {
|
||||
if (document.readyState === 'interactive') {
|
||||
load_done();
|
||||
}
|
||||
};
|
||||
})();
|
3
i/json/clients_Android.json
Normal file
3
i/json/clients_Android.json
Normal file
@ -0,0 +1,3 @@
|
||||
[
|
||||
"<strong><a href=\"https://f-droid.org/repo/de.pixart.messenger_302.apk\">Pix-Art Messenger</a></strong> - современный, полнофункциональный и сфокусированный на удобстве пользования"
|
||||
]
|
5
i/json/clients_Linux.json
Normal file
5
i/json/clients_Linux.json
Normal file
@ -0,0 +1,5 @@
|
||||
[
|
||||
"<strong><a href=\"https://dino.im/\">Dino</a></strong> - modern, clean and GNOME integrated",
|
||||
"<strong><a href=\"https://kaidan.im/\">Kaidan</a></strong> - modern, convergent and cross-platform",
|
||||
"<strong><a href=\"https://gajim.org/\">Gajim</a></strong> - полнофункциональный"
|
||||
]
|
3
i/json/clients_Windows.json
Normal file
3
i/json/clients_Windows.json
Normal file
@ -0,0 +1,3 @@
|
||||
[
|
||||
"<strong><a href=\"https://gajim.org/\">Gajim</a></strong> - полнофункционый"
|
||||
]
|
3
i/json/clients_iOS.json
Normal file
3
i/json/clients_iOS.json
Normal file
@ -0,0 +1,3 @@
|
||||
[
|
||||
"<strong><a href=\"https://itunes.apple.com/us/app/chatsecure/id464200063\">ChatSecure</a></strong> - Encrypted Messenger for iOS"
|
||||
]
|
19
i/lang/ru.json
Normal file
19
i/lang/ru.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"chat": {
|
||||
"title": "Приглашение от {{name}}",
|
||||
"heading": "{{name}} хочет связаться с вами",
|
||||
"button": "Добавить {{name}} в список контактов",
|
||||
"":""
|
||||
},
|
||||
"muc": {
|
||||
"title": "Приглашение в {{name}}",
|
||||
"heading": "Вы были приглашены в {{name}}",
|
||||
"button": "Вступить в групповой чат {{name}}",
|
||||
"":""
|
||||
},
|
||||
"clients": "Чтобы это произошло, вам нужно установить и настроить джаббер клиент, после этого посетить эту страницу снова.",
|
||||
"recommend": "Мы рекомендуем один из:",
|
||||
"checkfulllist": "Джаббер (XMPP) - это удобная и безопасная форма обмена сообщениями. Вы можете выбрать один из множества клиентов и иметь свободный выбор любого сервера для связи со всеми.",
|
||||
"xmppis": "Основано на <a href='https://i.kaidan.im/'>i.kaidan.im</a>",
|
||||
"":""
|
||||
}
|
Loading…
Reference in New Issue
Block a user