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 } ,
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" ,
} ,
] ;
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" ,
} ,
{
name : "Tensor2" ,
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/tensor2" ,
maturity : "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 C++ cross-platform desktop Matrix client" ,
} ,
2016-05-10 00:15:30 +02:00
{
name : "PTO (Perpetually Talking Online)" ,
2016-05-16 19:22:01 +02:00
logo : "img/pto-48px.png" ,
2016-05-10 00:15:30 +02:00
author : "Torrie Fischer" ,
homepage : "https://pto.im" ,
//room_url(alias) { return "irc://irc.matrix.org/" + alias },
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 > } ,
maturity : "Alpha" ,
comments : "Access any room anywhere in Matrix via good old IRC!" ,
} ,
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" ,
}
] ;
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 ;
}
2016-06-21 17:03:05 +02:00
if ( ! this . isAliasValid ( entity ) && ! this . isUserIdValid ( entity ) && ! this . isMsglinkValid ( entity ) && ! this . isRoomIdValid ( entity ) ) {
2016-05-09 03:36:18 +02:00
this . setState ( {
entity : entity ,
2016-05-20 18:09:04 +02:00
error : "Invalid room alias, user ID or message permalink '" + 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 ( ) ;
if ( ! this . isAliasValid ( entity ) && ! this . isUserIdValid ( entity ) ) {
this . setState ( { error : "Invalid room alias or user ID" } ) ;
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
} ,
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 ) ;
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 > ;
}
2016-05-09 03:36:18 +02:00
links = (
< div key = "links" className = "mxt_HomePage_links" >
< div className = "mxt_HomePage_links_intro" >
< p >
Matrix is an ecosystem for open and interoperable communication .
< / 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
}
if ( ! link ) return < div key = { client . name } / > ;
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
}
if ( ! instructions ) return < div key = { client . name } / > ;
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 } >
< input autoFocus className = "mxt_HomePage_inputBox_prompt" value = { this . state . entity } ref = "prompt" size = "36" type = "text" value = { this . state . value } placeholder = "#room:domain.com or @user:domain.com" / >
< 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
a < a href = "https://matrix.org/jira/browse/SPEC-5" > ubiquitous mx : //</a> URL scheme.
< / 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 >
) ;
}
} )