2016-05-09 03:36:18 +02:00
/ *
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
import React from 'react'
var linkable _clients = [
{
2016-09-19 16:10:41 +02:00
name : "Riot" ,
logo : "img/riot-48px.png" ,
author : "Vector Creations" ,
homepage : "https://riot.im" ,
room _url ( alias ) { return "https://riot.im/app/#/room/" + alias } ,
room _id _url ( id ) { return "https://riot.im/app/#/room/" + id } ,
user _url ( userId ) { return "https://riot.im/app/#/user/" + userId } ,
msg _url ( msg ) { return "https://riot.im/app/#/room/" + msg } ,
2017-11-16 12:59:59 +01:00
group _url ( group ) { return "https://riot.im/app/#/group/" + group } ,
2016-09-19 16:10:41 +02:00
maturity : "Stable" ,
2016-05-09 03:36:18 +02:00
comments : "Fully-featured Matrix client for Web, iOS & Android" ,
} ,
{
name : "Matrix Console" ,
2016-05-16 19:22:01 +02:00
logo : "img/console-48px.png" ,
2016-05-09 03:36:18 +02:00
author : "Matrix.org" ,
homepage : "https://matrix.org" ,
2016-05-10 00:15:30 +02:00
room _url ( alias ) { return "https://matrix.org/beta/#/room/" + alias } ,
2016-06-21 17:03:05 +02:00
room _id _url ( id ) { return "https://matrix.org/beta/#/room/" + id } ,
2016-05-09 03:36:18 +02:00
maturity : "Deprecated" ,
comments : "The original developer-focused client for Web, iOS & Android" ,
} ,
2017-08-22 11:20:32 +02:00
{
name : "Matrix-Static" ,
logo : "img/matrix-static-48px.png" ,
author : "Michael Telatynski" ,
homepage : "https://github.com/t3chguy/matrix-static" ,
2018-08-29 21:52:22 +02:00
room _url ( alias ) { return "https://view.matrix.org/alias/" + alias . replace ( /#/g , '%23' ) } ,
2017-08-22 11:20:32 +02:00
room _id _url ( id ) { return "https://view.matrix.org/room/" + id } ,
maturity : "Stable" ,
comments : "A static golang generated preview of public world readable Matrix rooms." ,
} ,
2016-05-09 03:36:18 +02:00
] ;
var unlinkable _clients = [
{
name : "Weechat" ,
2016-05-16 19:22:01 +02:00
logo : "img/weechat-48px.png" ,
2016-05-09 03:36:18 +02:00
author : "Tor Hveem" ,
homepage : "https://github.com/torhve/weechat-matrix-protocol-script" ,
maturity : "Late beta" ,
2016-05-10 00:15:30 +02:00
room _instructions ( alias ) { return < span > Type < code > / j o i n < b > { a l i a s } < / b > < / c o d e > < / s p a n > } ,
user _instructions ( userId ) { return < span > Type < code > / i n v i t e < b > { u s e r I d } < / b > < / c o d e > < / s p a n > } ,
2016-05-09 03:36:18 +02:00
comments : "Commandline Matrix interface using Weechat" ,
} ,
{
name : "Quaternion" ,
2016-05-16 19:22:01 +02:00
logo : "img/quaternion-48px.png" ,
2016-05-09 03:36:18 +02:00
author : "Felix Rohrbach" ,
homepage : "https://github.com/Fxrh/Quaternion" ,
maturity : "Late alpha" ,
2016-05-10 00:15:30 +02:00
room _instructions ( alias ) { return < span > Type < code > / j o i n < b > { a l i a s } < / b > < / c o d e > < / s p a n > } ,
user _instructions ( userId ) { return < span > Type < code > / i n v i t e < b > { u s e r I d } < / b > < / c o d e > < / s p a n > } ,
2016-05-09 03:36:18 +02:00
comments : "Qt5 and C++ cross-platform desktop Matrix client" ,
} ,
{
name : "Tensor" ,
2016-05-16 19:22:01 +02:00
logo : "img/tensor-48px.png" ,
2016-05-09 03:36:18 +02:00
author : "David A Roberts" ,
homepage : "https://github.com/davidar/tensor" ,
maturity : "Late alpha" ,
2016-05-10 00:15:30 +02:00
room _instructions ( alias ) { return < span > Type < code > / j o i n < b > { a l i a s } < / b > < / c o d e > < / s p a n > } ,
user _instructions ( userId ) { return < span > Type < code > / i n v i t e < b > { u s e r I d } < / b > < / c o d e > < / s p a n > } ,
2016-05-09 03:36:18 +02:00
comments : "QML and JS cross-platform desktop Matrix client" ,
} ,
2016-05-10 00:15:30 +02:00
{
2016-10-04 23:21:53 +02:00
name : "NaChat" ,
logo : "img/nachat.svg" ,
author : "Benjamin Saunders" ,
homepage : "https://github.com/Ralith/nachat" ,
2016-10-05 14:12:28 +02:00
maturity : "Late alpha" ,
2016-05-10 00:15:30 +02:00
room _instructions ( alias ) { return < span > Type < code > / j o i n < b > { a l i a s } < / b > < / c o d e > < / s p a n > } ,
user _instructions ( userId ) { return < span > Type < code > / i n v i t e < b > { u s e r I d } < / b > < / c o d e > < / s p a n > } ,
2016-10-04 23:21:53 +02:00
comments : "Qt5 and C++ cross-platform desktop Matrix client" ,
2016-05-10 00:15:30 +02:00
} ,
2017-10-22 20:13:17 +02:00
{
name : "Nheko" ,
logo : "img/nheko.png" ,
author : "Konstantinos Sideris" ,
homepage : "https://github.com/mujx/nheko" ,
maturity : "Late alpha" ,
room _instructions ( alias ) { return < span > Type < code > / j o i n < b > { a l i a s } < / b > < / c o d e > < / s p a n > } ,
comments : "Qt5 and C++ desktop client" ,
} ,
2016-05-09 03:36:18 +02:00
{
name : "Mclient.el" ,
logo : "" ,
author : "Ryan Rix" ,
homepage : "http://fort.kickass.systems:10082/cgit/personal/rrix/pub/matrix.el.git/" ,
maturity : "Alpha" ,
comments : "Matrix client for Gnu Emacs" ,
2017-11-18 16:20:07 +01:00
} ,
2018-04-18 22:46:20 +02:00
{
name : "Fractal" ,
logo : "img/org.gnome.Fractal.svg" ,
author : "Daniel Garcia Moreno" ,
maturity : "Alpha" ,
comments : "Matrix messaging app for GNOME written in Rust"
2018-08-14 12:49:26 +02:00
} ,
2017-11-18 16:20:07 +01:00
{
name : "Matrix IRCd" ,
logo : "img/ircd-48px.png" ,
author : "matrix.org" ,
homepage : "https://github.com/matrix-org/matrix-ircd" ,
room _instructions ( alias ) { return < span > Type < code > / j o i n < b > { a l i a s } < / b > < / c o d e > < / s p a n > } ,
maturity : "Alpha" ,
comments : "Access any room anywhere in Matrix via good old IRC!" ,
2017-11-18 16:14:05 +01:00
}
2016-05-09 03:36:18 +02:00
] ;
export default React . createClass ( {
getInitialState ( ) {
return {
error : null ,
entity : null ,
showLink : false ,
}
} ,
onHashChange ( ) {
2016-07-15 17:03:51 +02:00
var entity = unescape ( window . location . hash . substr ( 2 ) ) ; // strip off #/ prefix
2016-05-09 03:36:18 +02:00
if ( ! entity ) {
this . setState ( {
entity : null ,
showLink : false ,
2016-05-09 13:48:37 +02:00
error : null ,
2016-05-09 03:36:18 +02:00
} ) ;
return ;
}
2017-11-16 12:59:59 +01:00
if ( ! this . isAliasValid ( entity ) && ! this . isUserIdValid ( entity ) && ! this . isMsglinkValid ( entity ) && ! this . isRoomIdValid ( entity ) && ! this . isGroupValid ( entity ) ) {
2016-05-09 03:36:18 +02:00
this . setState ( {
entity : entity ,
2017-11-16 12:59:59 +01:00
error : "Invalid room alias, user ID, message permalink or group '" + entity + "'" ,
2016-05-09 03:36:18 +02:00
} ) ;
return ;
}
this . setState ( {
entity : entity ,
showLink : true ,
2016-05-09 13:48:37 +02:00
error : null ,
2016-05-09 03:36:18 +02:00
} ) ;
} ,
componentWillMount ( ) {
if ( window . location . hash ) {
this . onHashChange ( ) ;
}
} ,
componentDidMount ( ) {
window . addEventListener ( "hashchange" , this . onHashChange ) ;
} ,
componentWillUnmount ( ) {
window . removeEventListener ( "hashchange" , this . onHashChange ) ;
} ,
onSubmit ( ev ) {
ev . preventDefault ( ) ;
var entity = this . refs . prompt . value . trim ( ) ;
2017-11-16 12:59:59 +01:00
if ( ! this . isAliasValid ( entity ) && ! this . isUserIdValid ( entity ) && ! this . isGroupValid ( entity ) ) {
this . setState ( { error : "Invalid room alias, user ID or group" } ) ;
2016-05-09 03:36:18 +02:00
return ;
}
var loc = window . location ;
loc . hash = "#/" + entity ;
window . location . assign ( loc . href ) ;
this . setState ( {
showLink : true ,
entity : entity ,
2016-05-09 13:48:37 +02:00
error : null ,
2016-05-09 03:36:18 +02:00
} ) ;
} ,
// XXX: cargo-culted from matrix-react-sdk
isAliasValid ( alias ) {
// XXX: FIXME SPEC-1
2016-05-09 14:57:16 +02:00
return ( alias . match ( /^#([^\/:]+?):(.+)$/ ) && encodeURI ( alias ) === alias ) ;
2016-05-09 03:36:18 +02:00
} ,
2016-06-21 17:03:05 +02:00
isRoomIdValid ( id ) {
// XXX: FIXME SPEC-1
return ( id . match ( /^!([^\/:]+?):(.+)$/ ) && encodeURI ( id ) === id ) ;
} ,
2016-05-09 03:36:18 +02:00
isUserIdValid ( userId ) {
// XXX: FIXME SPEC-1
2016-05-09 14:57:16 +02:00
return ( userId . match ( /^@([^\/:]+?):(.+)$/ ) && encodeURI ( userId ) === userId ) ;
2016-05-09 03:36:18 +02:00
} ,
isMsglinkValid ( msglink ) {
// XXX: FIXME SPEC-1
2016-05-09 14:57:16 +02:00
console . log ( msglink ) ;
console . log ( encodeURI ( msglink ) ) ;
return ( msglink . match ( /^[\!#]([^\/:]+?):(.+?)\/\$([^\/:]+?):(.+?)$/ ) && encodeURI ( msglink ) === msglink ) ;
2016-05-09 03:36:18 +02:00
} ,
2017-11-16 12:59:59 +01:00
isGroupValid ( group ) {
console . log ( group ) ;
console . log ( encodeURI ( group ) ) ;
return ( group . match ( /^\+([^\/:]+?):(.+)$/ ) && encodeURI ( group ) === group ) ;
} ,
2016-05-09 03:36:18 +02:00
render ( ) {
var error ;
if ( this . state . error ) {
error = < div className = "mxt_HomePage_error" > { this . state . error } < / d i v >
}
var prompt ;
if ( this . state . showLink ) {
var link = "https://matrix.to/#/" + this . state . entity ;
var isRoom = this . isAliasValid ( this . state . entity ) ;
2016-06-21 17:03:05 +02:00
var isRoomId = this . isRoomIdValid ( this . state . entity ) ;
2016-05-09 03:36:18 +02:00
var isUser = this . isUserIdValid ( this . state . entity ) ;
var isMsg = this . isMsglinkValid ( this . state . entity ) ;
2017-11-16 12:59:59 +01:00
var isGroup = this . isGroupValid ( this . state . entity ) ;
2016-05-09 03:36:18 +02:00
var links ;
// name: "Vector",
// logo: "",
// author: "Vector.im",
// link: "https://vector.im",
// room_url: "https://vector.im/beta/#/room/",
// user_url: "https://vector.im/beta/#/user/",
// maturity: "Late beta",
// comments: "Fully-featured Matrix client for Web, iOS & Android",
2016-05-10 00:15:30 +02:00
var description ;
if ( isRoom ) {
description = < span > the < b > { this . state . entity } < / b > r o o m < / s p a n > ;
}
else if ( isUser ) {
description = < span > the user < b > { this . state . entity } < / b > < / s p a n > ;
}
else if ( isMsg ) {
description = < span > < b > this message < / b > < / s p a n > ;
}
2017-11-16 12:59:59 +01:00
else if ( isGroup ) {
description = < span > the < b > { this . state . entity } < / b > g r o u p < / s p a n > ;
}
2016-05-10 00:15:30 +02:00
2016-05-09 03:36:18 +02:00
links = (
< div key = "links" className = "mxt_HomePage_links" >
< div className = "mxt_HomePage_links_intro" >
< p >
2016-09-30 01:39:33 +02:00
< a href = "https://matrix.org" > Matrix < / a > i s a n e c o s y s t e m f o r o p e n a n d i n t e r o p e r a b l e c o m m u n i c a t i o n .
2016-05-09 03:36:18 +02:00
< / p >
< p >
2016-05-10 00:15:30 +02:00
To connect to { description } , please select an app :
2016-05-09 03:36:18 +02:00
< / p >
< / d i v >
2016-05-09 13:52:19 +02:00
< div className = "mxt_HomePage_link mxt_HomePage_link_title" >
< div className = "mxt_HomePage_link_logo" >
< / d i v >
< div className = "mxt_HomePage_link_name" >
Name
< / d i v >
< div className = "mxt_HomePage_link_comments" >
Description
< / d i v >
< div className = "mxt_HomePage_link_author" >
Author
< / d i v >
< div className = "mxt_HomePage_link_maturity" >
Maturity
< / d i v >
< div className = "mxt_HomePage_link_link" >
2016-05-17 00:00:37 +02:00
Access { isMsg ? "message" : < b > { this . state . entity } < / b > }
2016-05-09 13:52:19 +02:00
< / d i v >
< / d i v >
2016-05-09 03:36:18 +02:00
{ linkable _clients . map ( ( client ) => {
var link ;
if ( isRoom && client . room _url ) {
2016-05-10 00:15:30 +02:00
link = client . room _url ( this . state . entity ) ;
2016-05-09 03:36:18 +02:00
}
2016-06-21 17:03:05 +02:00
else if ( isRoomId && client . room _id _url ) {
link = client . room _id _url ( this . state . entity ) ;
}
2016-05-09 03:36:18 +02:00
else if ( isUser && client . user _url ) {
2016-05-10 00:15:30 +02:00
link = client . user _url ( this . state . entity ) ;
2016-05-09 03:36:18 +02:00
}
else if ( isMsg && client . msg _url ) {
2016-05-10 00:15:30 +02:00
link = client . msg _url ( this . state . entity ) ;
2016-05-09 03:36:18 +02:00
}
2017-11-16 12:59:59 +01:00
else if ( isGroup && client . group _url ) {
link = client . group _url ( this . state . entity ) ;
}
2016-09-19 16:49:17 +02:00
if ( ! link ) return null ;
2016-05-09 03:36:18 +02:00
return (
< div key = { client . name } className = "mxt_HomePage_link" >
< div className = "mxt_HomePage_link_logo" >
< a href = { link } > < img src = { client . logo } / > < / a >
< / d i v >
< div className = "mxt_HomePage_link_name" >
< a href = { link } > { client . name } < / a >
< div className = "mxt_HomePage_link_homepage" >
< a href = { client . homepage } > { client . homepage } < / a >
< / d i v >
< / d i v >
< div className = "mxt_HomePage_link_comments" >
{ client . comments }
< / d i v >
< div className = "mxt_HomePage_link_author" >
{ client . author }
< / d i v >
< div className = "mxt_HomePage_link_maturity" >
{ client . maturity }
< / d i v >
< div className = "mxt_HomePage_link_link" >
< a href = { link } > { link } < / a >
< / d i v >
< / d i v >
) ;
} ) }
{ unlinkable _clients . map ( ( client ) => {
var instructions ;
if ( isRoom && client . room _instructions ) {
2016-05-10 00:15:30 +02:00
instructions = client . room _instructions ( this . state . entity ) ;
2016-05-09 03:36:18 +02:00
}
else if ( isUser && client . user _instructions ) {
2016-05-10 00:15:30 +02:00
instructions = client . user _instructions ( this . state . entity ) ;
2016-05-09 03:36:18 +02:00
}
else if ( isMsg && client . msg _instructions ) {
2016-05-10 00:15:30 +02:00
instructions = client . msg _instructions ( this . state . entity ) ;
2016-05-09 03:36:18 +02:00
}
2017-11-16 12:59:59 +01:00
else if ( isGroup && client . group _instructions ) {
instructions = client . group _instructions ( this . state . entity ) ;
}
2016-09-19 16:49:17 +02:00
if ( ! instructions ) return null ;
2016-05-09 03:36:18 +02:00
return (
< div key = { client . name } className = "mxt_HomePage_link" >
< div className = "mxt_HomePage_link_logo" >
< a href = { client . homepage } > < img src = { client . logo } / > < / a >
< / d i v >
< div className = "mxt_HomePage_link_name" >
< a href = { client . homepage } > { client . name } < / a >
< div className = "mxt_HomePage_link_homepage" >
< a href = { client . homepage } > { client . homepage } < / a >
< / d i v >
< / d i v >
< div className = "mxt_HomePage_link_comments" >
{ client . comments }
< / d i v >
< div className = "mxt_HomePage_link_author" >
{ client . author }
< / d i v >
< div className = "mxt_HomePage_link_maturity" >
{ client . maturity }
< / d i v >
< div className = "mxt_HomePage_link_instructions" >
{ instructions }
< / d i v >
< / d i v >
) ;
} ) }
< p >
To add clients to this list , < a href = "https://matrix.to/#/#matrix-dev:matrix.org" > please contact us < / a > o r
simply send us a pull request < a href = "https://github.com/matrix-org/matrix.to" > on github < / a > !
< / p >
< / d i v >
) ;
prompt = [
< div key = "inputbox" className = "mxt_HomePage_inputBox" >
< a href = { link } className = "mxt_HomePage_inputBox_link" > { link } < / a >
{ error }
< / d i v > ,
links
] ;
}
else {
prompt = [
< div key = "inputBox" className = "mxt_HomePage_inputBox" >
< form onSubmit = { this . onSubmit } >
2017-11-16 13:02:13 +01:00
< input autoFocus className = "mxt_HomePage_inputBox_prompt" value = { this . state . entity } ref = "prompt" size = "36" type = "text" placeholder = "#room:example.com, @user:example.com or +group:example.com" / >
2016-05-09 03:36:18 +02:00
< input className = "mxt_HomePage_inputBox_button" type = "submit" value = "Get link!" / >
< / f o r m >
{ error }
< / d i v > ,
< div key = "cta" className = "mxt_HomePage_cta" >
Create shareable links to Matrix rooms , users or messages < br / >
without being tied to a specific app .
< / d i v >
] ;
}
return (
< div className = "mxt_HomePage" >
< a href = "#" >
< img className = "mxt_HomePage_logo" src = "img/matrix-logo.svg" width = "352" height = "150" alt = "[matrix]" / >
< / a >
{ prompt }
< div className = "mxt_HomePage_info" >
< h3 > About < / h 3 >
< p >
Matrix . to is a simple stateless URL redirecting service
which lets users share links to entities in the < a href = "https://matrix.org" > Matrix . org
< / a > e c o s y s t e m w i t h o u t b e i n g t i e d t o a n y s p e c i f i c a p p . T h i s l e t s u s e r s c h o o s e t h e i r o w n f a v o u r i t e
Matrix client to participate in conversations rather than being forced to use the same app as
whoever sent the link .
< / p >
< p >
The service preserves user privacy by not
sharing any information about the links being followed with the Matrix . to server - the
redirection is calculated entirely clientside using JavaScript .
< / p >
< p >
Links are designed to be human - friendly , both for reading and constructing , and are
essentially a compatibility step in the journey towards
2017-01-03 01:07:07 +01:00
a < a href = "https://github.com/matrix-org/matrix-doc/issues/455" > ubiquitous mx : //</a> URL scheme.
2016-05-09 03:36:18 +02:00
< / p >
2016-05-16 19:22:01 +02:00
< p >
As with all of Matrix , Matrix . to is released as open source under the terms of
the < a href = "http://www.apache.org/licenses/LICENSE-2.0" > Apache License v2 . 0 < / a > - g e t t h e s o u r c e
from < a href = "https://github.com/matrix-org/matrix.to" > Github < / a > .
< / p >
2016-05-09 03:36:18 +02:00
< / d i v >
< / d i v >
) ;
}
} )