2017-06-21 03:14:26 +02:00
import fuzzysearch from 'fuzzysearch' ;
2017-07-12 02:50:27 +02:00
import blueslip from './../blueslip' ;
2017-06-21 03:14:26 +02:00
2017-07-08 02:28:18 +02:00
const ELECTRON _APP _VERSION = "1.2.0-beta" ;
2017-07-26 20:02:08 +02:00
const ELECTRON _APP _URL _LINUX = "https://github.com/zulip/zulip-electron/releases/download/v" + ELECTRON _APP _VERSION + "/Zulip-" + ELECTRON _APP _VERSION + "-x86_64.AppImage" ;
const ELECTRON _APP _URL _MAC = "https://github.com/zulip/zulip-electron/releases/download/v" + ELECTRON _APP _VERSION + "/Zulip-" + ELECTRON _APP _VERSION + ".dmg" ;
const ELECTRON _APP _URL _WINDOWS = "https://github.com/zulip/zulip-electron/releases/download/v" + ELECTRON _APP _VERSION + "/Zulip-Web-Setup-" + ELECTRON _APP _VERSION + ".exe" ;
2017-07-08 02:28:18 +02:00
2017-02-28 01:45:25 +01:00
// this will either smooth scroll to an anchor where the `name`
// is the same as the `scroll-to` reference, or to a px height
// (as specified like `scroll-to='0px'`).
var ScrollTo = function ( ) {
$ ( "[scroll-to]" ) . click ( function ( ) {
var sel = $ ( this ) . attr ( "scroll-to" ) ;
// if the `scroll-to` is a parse-able pixel value like `50px`,
// then use that as the scrollTop, else assume it is a selector name
// and find the `offsetTop`.
var top = /\dpx/ . test ( sel ) ?
parseInt ( sel , 10 ) :
$ ( "[name='" + sel + "']" ) . offset ( ) . top ;
$ ( "body" ) . animate ( { scrollTop : top + "px" } , 300 ) ;
} ) ;
} ;
2017-07-01 01:29:15 +02:00
var detectPath = function ( pathname ) {
var match = ( pathname || window . location . pathname ) . match ( /(\/\w+)?\/(.+)\// ) ;
if ( match !== null ) {
return match [ 2 ] ;
}
} ;
2017-02-28 01:45:55 +01:00
// these are events that are only to run on the integrations page.
// check if the page location is integrations.
var integration _events = function ( ) {
2017-06-21 03:14:26 +02:00
var integrations = $ ( '.integration-lozenges' ) . children ( ) . toArray ( ) ;
2017-04-06 02:21:20 +02:00
var scroll _top = 0 ;
2017-02-28 01:45:55 +01:00
$ ( "a.title" )
. addClass ( "show-integral" )
. prepend ( $ ( "<span class='integral'>∫</span>" ) )
. hover ( function ( ) {
$ ( ".integral" ) . css ( "display" , "inline" ) ;
var width = $ ( ".integral" ) . width ( ) ;
$ ( "a.title" ) . css ( "left" , - 1 * width ) ;
} ,
function ( ) {
$ ( ".integral" ) . css ( "display" , "none" ) ;
$ ( "a.title" ) . css ( "left" , 0 ) ;
}
) ;
2017-07-10 23:44:00 +02:00
function adjust _font _sizing ( ) {
$ ( '.integration-lozenge' ) . toArray ( ) . forEach ( function ( integration ) {
var $integration _name = $ ( integration ) . find ( '.integration-name' ) ;
var $integration _category = $ ( integration ) . find ( '.integration-category' ) ;
// if the text has wrapped to two lines, decrease font-size
if ( $integration _name . height ( ) > 30 ) {
$integration _name . css ( 'font-size' , '1em' ) ;
if ( $integration _name . height ( ) > 30 ) {
$integration _name . css ( 'font-size' , '.95em' ) ;
}
}
if ( $integration _category . height ( ) > 30 ) {
$integration _category . css ( 'font-size' , '.8em' ) ;
if ( $integration _category . height ( ) > 30 ) {
$integration _category . css ( 'font-size' , '.75em' ) ;
}
}
} ) ;
}
adjust _font _sizing ( ) ;
$ ( window ) . resize ( adjust _font _sizing ) ;
2017-02-28 01:45:55 +01:00
var $lozenge _icon ;
var currentblock ;
var instructionbox = $ ( "#integration-instruction-block" ) ;
var hashes = $ ( '.integration-instructions' ) . map ( function ( ) {
return this . id || null ;
} ) . get ( ) ;
var show _integration = function ( hash ) {
// the version of the hash without the leading "#".
var _hash = hash . replace ( /^#/ , "" ) ;
2017-07-12 02:50:27 +02:00
var integration _name = _hash ;
$ . get ( {
url : '/integrations/doc/' + integration _name ,
dataType : 'html' ,
success : function ( doc ) {
$ ( '#' + integration _name + '.integration-instructions .help-content' ) . html ( doc ) ;
} ,
error : function ( err ) {
blueslip . error ( "Integration documentation for '" + integration _name + "' not found." , err ) ;
} ,
} ) ;
2017-02-28 01:45:55 +01:00
2017-04-06 22:45:24 +02:00
// clear out the integrations instructions that may exist in the instruction
// block from a previous hash.
$ ( "#integration-instruction-block .integration-instructions" )
. appendTo ( "#integration-instructions-group" ) ;
2017-02-28 01:45:55 +01:00
if ( hashes . indexOf ( _hash ) > - 1 ) {
$lozenge _icon = $ ( ".integration-lozenges .integration-lozenge.integration-" + _hash ) . clone ( true ) ;
currentblock = $ ( hash ) ;
2017-03-21 20:03:24 +01:00
instructionbox . hide ( ) . children ( ".integration-lozenge" ) . replaceWith ( $lozenge _icon ) ;
2017-04-06 22:45:24 +02:00
instructionbox . append ( $lozenge _icon ) ;
2017-02-28 01:45:55 +01:00
$ ( ".inner-content" ) . removeClass ( "show" ) ;
setTimeout ( function ( ) {
instructionbox . hide ( ) ;
2017-06-13 01:06:47 +02:00
$ ( ".integration-categories-dropdown" ) . css ( 'display' , 'none' ) ;
$ ( ".integrations .catalog" ) . addClass ( 'hide' ) ;
$ ( ".extra, #integration-main-text, #integration-search" ) . css ( "display" , "none" ) ;
2017-02-28 01:45:55 +01:00
instructionbox . append ( currentblock ) ;
instructionbox . show ( ) ;
$ ( "#integration-list-link" ) . css ( "display" , "block" ) ;
$ ( ".inner-content" ) . addClass ( "show" ) ;
} , 300 ) ;
2017-04-06 02:21:20 +02:00
$ ( "html, body" ) . animate ( { scrollTop : 0 } , 200 ) ;
2017-02-28 01:45:55 +01:00
}
} ;
function update _hash ( ) {
2017-04-06 02:21:20 +02:00
var hash = window . location . hash ;
2017-02-28 01:45:55 +01:00
2017-06-13 01:06:47 +02:00
if ( hash && hash !== '#' && hash !== '#hubot-integrations' ) {
2017-04-06 02:21:20 +02:00
scroll _top = $ ( "body" ) . scrollTop ( ) ;
2017-02-28 01:45:55 +01:00
show _integration ( window . location . hash ) ;
} else if ( currentblock && $lozenge _icon ) {
$ ( ".inner-content" ) . removeClass ( "show" ) ;
setTimeout ( function ( ) {
$ ( "#integration-list-link" ) . css ( "display" , "none" ) ;
2017-06-13 01:06:47 +02:00
$ ( ".extra, #integration-main-text, #integration-search" ) . show ( ) ;
2017-02-28 01:45:55 +01:00
instructionbox . hide ( ) ;
$lozenge _icon . remove ( ) ;
currentblock . appendTo ( "#integration-instructions-group" ) ;
2017-06-13 01:06:47 +02:00
2017-02-28 01:45:55 +01:00
$ ( ".inner-content" ) . addClass ( "show" ) ;
2017-06-13 01:06:47 +02:00
$ ( ".integration-categories-dropdown" ) . css ( 'display' , '' ) ;
$ ( ".integrations .catalog" ) . removeClass ( 'hide' ) ;
2017-04-06 02:21:20 +02:00
$ ( 'html, body' ) . animate ( { scrollTop : scroll _top } , 0 ) ;
2017-02-28 01:45:55 +01:00
} , 300 ) ;
} else {
$ ( ".inner-content" ) . addClass ( "show" ) ;
2017-06-13 01:06:47 +02:00
$ ( ".integration-categories-dropdown" ) . removeClass ( 'hide' ) ;
$ ( ".integrations .catalog" ) . removeClass ( 'hide' ) ;
2017-02-28 01:45:55 +01:00
}
2017-07-10 23:44:00 +02:00
adjust _font _sizing ( ) ;
2017-02-28 01:45:55 +01:00
}
window . onhashchange = update _hash ;
update _hash ( ) ;
2017-04-06 02:21:20 +02:00
// this needs to happen because when you link to "#" it will scroll to the
// top of the page.
$ ( "#integration-list-link" ) . click ( function ( e ) {
var scroll _height = $ ( "body" ) . scrollTop ( ) ;
window . location . hash = "#" ;
$ ( "body" ) . scrollTop ( scroll _height ) ;
e . preventDefault ( ) ;
} ) ;
2017-06-13 01:06:47 +02:00
2017-06-21 03:14:26 +02:00
$ ( '#integration-search input[type="text"]' ) . keypress ( function ( e ) {
if ( e . which === 13 && e . target . value !== '' ) {
for ( var i = 0 ; i < integrations . length ; i += 1 ) {
var integration = $ ( integrations [ i ] ) . find ( '.integration-lozenge' ) ;
if ( $ ( integration ) . css ( 'display' ) !== 'none' ) {
$ ( integration ) . closest ( 'a' ) [ 0 ] . click ( ) ;
break ;
}
}
}
} ) ;
$ ( window ) . scroll ( function ( ) {
if ( document . body . scrollTop > 330 ) {
$ ( '.integration-categories-sidebar' ) . addClass ( 'sticky' ) ;
} else {
$ ( '.integration-categories-sidebar' ) . removeClass ( 'sticky' ) ;
2017-06-13 01:06:47 +02:00
}
} ) ;
2017-02-28 01:45:55 +01:00
} ;
2017-06-21 03:14:26 +02:00
function integration _search ( ) {
var integrations = $ ( '.integration-lozenges' ) . children ( ) . toArray ( ) ;
var current _category = 'All' ;
var current _query = '' ;
function update _categories ( ) {
$ ( '.integration-category' ) . removeClass ( 'selected' ) ;
$ ( '[data-category="' + current _category + '"]' ) . addClass ( 'selected' ) ;
}
var update _integrations = _ . debounce ( function ( ) {
integrations . forEach ( function ( integration ) {
var $integration = $ ( integration ) . find ( '.integration-lozenge' ) ;
2017-07-11 01:24:48 +02:00
var $integration _category = $integration . find ( '.integration-category' ) ;
if ( current _category !== 'All' ) {
$integration _category . css ( 'display' , 'none' ) ;
$integration . addClass ( 'without-category' ) ;
} else {
$integration _category . css ( 'display' , '' ) ;
$integration . removeClass ( 'without-category' ) ;
}
2017-06-21 03:14:26 +02:00
2017-07-11 03:18:58 +02:00
if ( ! $integration . hasClass ( 'integration-create-your-own' ) ) {
var display =
fuzzysearch ( current _query , $integration . data ( 'name' ) . toLowerCase ( ) ) &&
( $integration . data ( 'categories' ) . indexOf ( current _category ) !== - 1 ||
current _category === 'All' ) ;
if ( display ) {
$integration . css ( 'display' , 'inline-block' ) ;
} else {
$integration . css ( 'display' , 'none' ) ;
}
2017-06-21 03:14:26 +02:00
}
} ) ;
} , 50 ) ;
function change _category ( category ) {
$ ( '.integration-lozenges' ) . css ( 'opacity' , 0 ) ;
current _category = category ;
update _categories ( ) ;
update _integrations ( ) ;
$ ( '.integration-lozenges' ) . animate (
{ opacity : 1 } ,
{ duration : 400 }
) ;
}
function run _search ( query ) {
current _query = query . toLowerCase ( ) ;
update _integrations ( ) ;
}
$ ( '.integrations .integration-category' ) . on ( 'click' , function ( e ) {
var category = $ ( e . target ) . data ( 'category' ) ;
if ( category !== current _category ) {
change _category ( category ) ;
}
} ) ;
$ ( ".integrations .searchbar input[type='text']" ) . on ( 'input' , function ( e ) {
run _search ( e . target . value ) ;
} ) ;
}
2017-04-20 20:44:49 +02:00
var hello _events = function ( ) {
var counter = 0 ;
$ ( window ) . scroll ( function ( ) {
if ( counter % 2 === 0 ) {
$ ( ".screen.hero-screen .message-feed" ) . css ( "transform" , "translateY(-" + $ ( this ) . scrollTop ( ) / 5 + "px)" ) ;
}
counter += 1 ;
} ) ;
$ ( ".footer" ) . addClass ( "hello" ) ;
} ;
2017-07-08 02:28:18 +02:00
var apps _events = function ( ) {
var version ;
var info = {
windows : {
image : "/static/images/landing-page/microsoft.png" ,
alt : "Windows" ,
description : "Zulip for Windows is even better than Zulip on the web, with a cleaner look, tray integration, native notifications, and support for multiple Zulip accounts." ,
link : ELECTRON _APP _URL _WINDOWS ,
} ,
mac : {
image : "/static/images/landing-page/macbook.png" ,
alt : "MacOS" ,
description : "Zulip on MacOS is even better than Zulip on the web, with a cleaner look, tray integration, native notifications, and support for multiple Zulip accounts." ,
link : ELECTRON _APP _URL _MAC ,
} ,
android : {
image : "/static/images/app-screenshots/zulip-android.png" ,
alt : "Android" ,
description : "Zulip's native Android app makes it easy to keep up while on the go." ,
link : "https://play.google.com/store/apps/details?id=com.zulip.android" ,
} ,
ios : {
image : "/static/images/app-screenshots/zulip-iphone-rough.png" ,
alt : "iOS" ,
description : "Zulip's native iOS app makes it easy to keep up while on the go." ,
link : "https://itunes.apple.com/us/app/zulip/id1203036395" ,
} ,
linux : {
image : "/static/images/landing-page/ubuntu.png" ,
alt : "Linux" ,
description : "Zulip on the Linux desktop is even better than Zulip on the web, with a cleaner look, tray integration, native notifications, and support for multiple Zulip accounts." ,
link : ELECTRON _APP _URL _LINUX ,
} ,
} ;
var nav _version = {
Win : "windows" ,
MacIntel : "mac" ,
Linux : "linux" ,
iP : "ios" ,
} ;
// if the hash is not a valid section, then identify it.
version = window . location . hash . replace ( /^#/ , "" ) ;
if ( info [ version ] ) {
window . location . hash = version ;
} else {
for ( var x in nav _version ) {
if ( navigator . platform . indexOf ( x ) !== - 1 ) {
window . location . hash = nav _version [ x ] ;
version = nav _version [ x ] ;
break ;
}
}
if ( ! version || ! info [ version ] ) {
version = "mac" ;
}
window . location . hash = version ;
}
var update _version = function ( version ) {
var version _info = info [ version ] ;
$ ( ".info .platform" ) . text ( version _info . alt ) ;
$ ( ".info .description" ) . text ( version _info . description ) ;
$ ( ".info .link" ) . attr ( "href" , version _info . link ) ;
$ ( ".image img" ) . attr ( "src" , version _info . image ) ;
} ;
window . onhashchange = function ( ) {
update _version ( window . location . hash . substr ( 1 ) ) ;
} ;
update _version ( version ) ;
$ ( ".apps > .icon" ) . click ( function ( ) {
$ ( "body" ) . animate ( { scrollTop : 0 } , 200 ) ;
} ) ;
} ;
2017-02-28 01:45:25 +01:00
var events = function ( ) {
ScrollTo ( ) ;
$ ( "a" ) . click ( function ( e ) {
// if the pathname is different than what we are already on, run the
// custom transition function.
2017-07-08 02:28:18 +02:00
if ( window . location . pathname !== this . pathname && ! this . hasAttribute ( "download" ) &&
! /no-action/ . test ( this . className ) ) {
2017-02-28 01:45:25 +01:00
e . preventDefault ( ) ;
$ ( ".portico-landing" ) . removeClass ( "show" ) ;
setTimeout ( function ( ) {
window . location . href = $ ( this ) . attr ( "href" ) ;
2017-06-30 00:42:39 +02:00
} . on ( this ) , 500 ) ;
2017-02-28 01:45:25 +01:00
}
} ) ;
// get the location url like `zulipchat.com/features/`, cut off the trailing
// `/` and then split by `/` to get ["zulipchat.com", "features"], then
// pop the last element to get the current section (eg. `features`).
2017-03-21 01:41:50 +01:00
var location = window . location . pathname . replace ( /\/#*$/ , "" ) . split ( /\// ) . pop ( ) ;
2017-02-28 01:45:25 +01:00
$ ( "[on-page='" + location + "']" ) . addClass ( "active" ) ;
$ ( "body" ) . click ( function ( e ) {
var $e = $ ( e . target ) ;
2017-06-12 22:05:29 +02:00
if ( $e . is ( "nav ul .exit" ) ) {
2017-02-28 01:45:25 +01:00
$ ( "nav ul" ) . removeClass ( "show" ) ;
}
} ) ;
2017-05-10 19:55:40 +02:00
$ ( ".hamburger" ) . click ( function ( ) {
2017-02-28 01:45:25 +01:00
$ ( "nav ul" ) . addClass ( "show" ) ;
} ) ;
2017-05-10 19:55:40 +02:00
2017-07-08 02:28:18 +02:00
if ( detectPath ( ) === "apps" ) {
apps _events ( ) ;
}
2017-02-28 01:45:25 +01:00
2017-07-01 01:29:15 +02:00
if ( detectPath ( ) === "integrations" ) {
2017-02-28 01:45:55 +01:00
integration _events ( ) ;
2017-06-21 03:14:26 +02:00
integration _search ( ) ;
2017-02-28 01:45:55 +01:00
}
2017-04-20 20:44:49 +02:00
2017-07-01 01:29:15 +02:00
if ( detectPath ( ) === "hello" ) {
2017-04-20 20:44:49 +02:00
hello _events ( ) ;
}
2017-06-13 01:06:47 +02:00
$ ( '.integration-categories-dropdown .dropdown-toggle' ) . click ( function ( ) {
var $dropdown _list = $ ( '.integration-categories-dropdown .dropdown-list' ) ;
$dropdown _list . toggle ( ) ;
var $dropdown _icon = $ ( '.integration-categories-dropdown i' ) ;
if ( $dropdown _list . css ( 'display' ) === 'none' ) {
$dropdown _icon
. removeClass ( 'icon-vector-angle-down' )
. addClass ( 'icon-vector-angle-right' ) ;
} else {
$dropdown _icon
. removeClass ( 'icon-vector-angle-right' )
. addClass ( 'icon-vector-angle-down' ) ;
}
} ) ;
2017-02-28 01:45:25 +01:00
} ;
2017-06-21 03:14:26 +02:00
2017-02-28 01:45:25 +01:00
// run this callback when the page is determined to have loaded.
var load = function ( ) {
// show the .portico-landing when the document is loaded.
setTimeout ( function ( ) {
$ ( ".portico-landing" ) . addClass ( "show" ) ;
} , 200 ) ;
// display the `x-grad` element a second after load so that the slide up
// transition on the .portico-landing is nice and smooth.
setTimeout ( function ( ) {
$ ( "x-grad" ) . addClass ( "show" ) ;
} , 1000 ) ;
2017-06-21 03:14:26 +02:00
// Set up events / categories / search
2017-02-28 01:45:25 +01:00
events ( ) ;
} ;
if ( document . readyState === "complete" ) {
load ( ) ;
} else {
$ ( document ) . ready ( load ) ;
}