diff --git a/examples/trivial/fonts b/examples/trivial/fonts new file mode 120000 index 0000000000..27f04cad54 --- /dev/null +++ b/examples/trivial/fonts @@ -0,0 +1 @@ +../../skins/base/fonts/ \ No newline at end of file diff --git a/examples/trivial/img b/examples/trivial/img new file mode 120000 index 0000000000..0d3ef0e2f2 --- /dev/null +++ b/examples/trivial/img @@ -0,0 +1 @@ +../../skins/base/img \ No newline at end of file diff --git a/examples/trivial/index.html b/examples/trivial/index.html index 4ec5b9093a..1258b78af4 100644 --- a/examples/trivial/index.html +++ b/examples/trivial/index.html @@ -2,9 +2,22 @@ - Matrix React SDK Example + vector + + + +
diff --git a/examples/trivial/index.js b/examples/trivial/index.js index 2be9054954..b601cfce6b 100644 --- a/examples/trivial/index.js +++ b/examples/trivial/index.js @@ -40,9 +40,17 @@ function routeUrl(location) { } } window.matrixChat.showScreen('register', params); + } else { + window.matrixChat.showScreen(location.hash.substring(2)); } } +function onHashChange(ev) { + routeUrl(window.location); +} + +window.addEventListener('hashchange', onHashChange); + var loaded = false; window.onload = function() { diff --git a/examples/trivial/media/busy.mp3 b/examples/trivial/media/busy.mp3 new file mode 100644 index 0000000000..fec27ba4c5 Binary files /dev/null and b/examples/trivial/media/busy.mp3 differ diff --git a/examples/trivial/media/busy.ogg b/examples/trivial/media/busy.ogg new file mode 100644 index 0000000000..5d64a7d0d9 Binary files /dev/null and b/examples/trivial/media/busy.ogg differ diff --git a/examples/trivial/media/callend.mp3 b/examples/trivial/media/callend.mp3 new file mode 100644 index 0000000000..50c34e5640 Binary files /dev/null and b/examples/trivial/media/callend.mp3 differ diff --git a/examples/trivial/media/callend.ogg b/examples/trivial/media/callend.ogg new file mode 100644 index 0000000000..927ce1f634 Binary files /dev/null and b/examples/trivial/media/callend.ogg differ diff --git a/examples/trivial/media/message.mp3 b/examples/trivial/media/message.mp3 new file mode 100644 index 0000000000..942adbe85d Binary files /dev/null and b/examples/trivial/media/message.mp3 differ diff --git a/examples/trivial/media/message.ogg b/examples/trivial/media/message.ogg new file mode 100644 index 0000000000..516114b852 Binary files /dev/null and b/examples/trivial/media/message.ogg differ diff --git a/examples/trivial/media/ring.mp3 b/examples/trivial/media/ring.mp3 new file mode 100644 index 0000000000..3c3cdde3f9 Binary files /dev/null and b/examples/trivial/media/ring.mp3 differ diff --git a/examples/trivial/media/ring.ogg b/examples/trivial/media/ring.ogg new file mode 100644 index 0000000000..de49b8ae6f Binary files /dev/null and b/examples/trivial/media/ring.ogg differ diff --git a/examples/trivial/media/ringback.mp3 b/examples/trivial/media/ringback.mp3 new file mode 100644 index 0000000000..6ee34bf395 Binary files /dev/null and b/examples/trivial/media/ringback.mp3 differ diff --git a/examples/trivial/media/ringback.ogg b/examples/trivial/media/ringback.ogg new file mode 100644 index 0000000000..7dbfdcd017 Binary files /dev/null and b/examples/trivial/media/ringback.ogg differ diff --git a/skins/base/css/atoms/MessageTimestamp.css b/skins/base/css/atoms/MessageTimestamp.css index 62b3065661..b3c6850949 100644 --- a/skins/base/css/atoms/MessageTimestamp.css +++ b/skins/base/css/atoms/MessageTimestamp.css @@ -15,6 +15,4 @@ limitations under the License. */ .mx_MessageTimestamp { - display: table-cell; - white-space: pre; } diff --git a/skins/base/css/common.css b/skins/base/css/common.css index 5153f97065..55b9a6db31 100644 --- a/skins/base/css/common.css +++ b/skins/base/css/common.css @@ -15,9 +15,94 @@ limitations under the License. */ body { - font-family: Helvetica, Arial, Sans-Serif; + font-family: 'Lato', Helvetica, Arial, Sans-Serif; + font-size: 16px; + color: #454545; + border: 0px; + margin: 0px; } div.error { color: red; } + +h2 { + color: #80cef4; + font-weight: 400; + font-size: 20px; + margin-top: 16px; + margin-bottom: 16px; +} + +/* FIXME: show them on hoverover, and fix for firefox */ +::-webkit-scrollbar { + display: none; +} + +html { + overflow: -moz-scrollbars-none; +} + +.mx_Dialog_Background { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: #000; + opacity: 0.2; + z-index: 2000; +} + +.mx_Dialog_Wrapper { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.mx_Dialog { + background-color: #fff; + color: #747474; + text-align: center; + margin: auto; + max-width: 500px; + z-index: 2010; + font-weight: 300; + font-size: 16px; + position: relative; + border-radius: 8px; + top: 200px; +} + +.mx_Dialog_content { + margin: 35px; +} + +.mx_Dialog_buttons { + padding-bottom: 35px; +} + +.mx_Dialog button { + border: 0px; + height: 36px; + border-radius: 36px; + font-weight: 400; + font-size: 16px; + color: #fff; + background-color: #80cef4; + margin-left: 8px; + margin-right: 8px; + padding-left: 1em; + padding-right: 1em; +} + +.mx_ErrorDialogTitle { + min-height: 16px; + padding: 12px; + border-bottom: 1px solid #a9dbf4; + font-weight: bold; + font-size: 20px; + line-height: 1.4; +} \ No newline at end of file diff --git a/skins/base/css/molecules/MNoticeTile.css b/skins/base/css/molecules/MNoticeTile.css index cac13e9b89..0e9c3ca144 100644 --- a/skins/base/css/molecules/MNoticeTile.css +++ b/skins/base/css/molecules/MNoticeTile.css @@ -15,4 +15,5 @@ limitations under the License. */ .mx_MNoticeTile { + opacity: 0.5; } diff --git a/skins/base/css/molecules/MatrixToolbar.css b/skins/base/css/molecules/MatrixToolbar.css new file mode 100644 index 0000000000..1e35ee270f --- /dev/null +++ b/skins/base/css/molecules/MatrixToolbar.css @@ -0,0 +1,28 @@ +/* +Copyright 2015 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. +*/ + +.mx_MatrixToolbar { + width: 100%; + text-align: center; + background-color: #ff0064; + color: #fff; + font-weight: bold; + padding: 6px; +} + +.mx_MatrixToolbar button { + margin-left: 12px; +} \ No newline at end of file diff --git a/skins/base/css/molecules/MemberInfo.css b/skins/base/css/molecules/MemberInfo.css new file mode 100644 index 0000000000..144212d766 --- /dev/null +++ b/skins/base/css/molecules/MemberInfo.css @@ -0,0 +1,73 @@ +/* +Copyright 2015 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. +*/ + +.mx_MemberInfo { + text-align: center; + border: 1px solid #a9dbf4; + border-radius: 8px; + background-color: #fff; + position: absolute; + width: 200px; + margin-left: -295px; + margin-top: 0px; + z-index: 1000; + padding: 6px; +} + +.mx_MemberInfo_chevron { + padding: 12px; + position: absolute; + right: -21px; + top: 0px; +} + +/* + * a hacky shim to extend the hitmask of the overlay to overlap + * better with the main menu itself + */ +.mx_MemberInfo_shim { + position: absolute; + left: 212px; + width: 40px; + height: 100%; +} + +.mx_MemberInfo_avatar { + padding: 6px; +} + +.mx_MemberInfo_avatarImg { + border-radius: 128px; +} + +.mx_MemberInfo_field { + padding: 6px; + overflow: hidden; + text-overflow: ellipsis; +} + +.mx_MemberInfo_button { + vertical-align: middle; + max-width: 100px; + height: 36px; + background-color: #50e3c2; + line-height: 36px; + border-radius: 36px; + color: #fff; + margin: auto; + margin-top: 6px; + margin-bottom: 6px; +} diff --git a/skins/base/css/molecules/MemberTile.css b/skins/base/css/molecules/MemberTile.css new file mode 100644 index 0000000000..099542a87c --- /dev/null +++ b/skins/base/css/molecules/MemberTile.css @@ -0,0 +1,99 @@ +/* +Copyright 2015 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. +*/ + +.mx_MemberTile { + cursor: pointer; + display: table-row; + height: 49px; +} + +.mx_MemberTile_avatar { + display: table-cell; + padding-right: 12px; + padding-top: 3px; + padding-bottom: 3px; + vertical-align: middle; + width: 40px; + height: 40px; + position: relative; +} + +.mx_MemberTile_avatarImg { + z-index: 20; + border-radius: 20px; + background-color: #dbdbdb; +} + +.mx_MemberTile_inviteEditing { + display: initial ! important; +} + +.mx_MemberTile_inviteEditing .mx_MemberTile_avatar { + display: none; +} + +.mx_MemberTile_inviteEditing .mx_MemberTile_name { + width: 200px; +} + +.mx_MemberTile_inviteEditing .mx_MemberTile_name input { + border-radius: 3px; + border: 1px solid #c7c7c7; + font-weight: 300; + font-size: 14px; + padding: 9px; + margin-top: 6px; +} + +.mx_MemberTile_power { + z-index: 10; + position: absolute; + width: 48px; + height: 48px; + left: -4px; + top: -1px; +} + +.mx_MemberTile_name { + display: table-cell; + vertical-align: middle; + overflow: hidden; + text-overflow: ellipsis; +} + +.mx_MemberTile_nameWrapper { + display: table-cell; + vertical-align: middle; + overflow: hidden; + text-overflow: ellipsis; +} + +.mx_MemberTile_nameSpan { +} + +.mx_MemberTile_unavailable .mx_MemberTile_avatar, +.mx_MemberTile_unavailable .mx_MemberTile_name, +.mx_MemberTile_unavailable .mx_MemberTile_nameSpan +{ + opacity: 0.75; +} + +.mx_MemberTile_offline .mx_MemberTile_avatar, +.mx_MemberTile_offline .mx_MemberTile_name, +.mx_MemberTile_offline .mx_MemberTile_nameSpan +{ + opacity: 0.5; +} \ No newline at end of file diff --git a/skins/base/css/molecules/MessageComposer.css b/skins/base/css/molecules/MessageComposer.css index 829e25a938..af4934ee2a 100644 --- a/skins/base/css/molecules/MessageComposer.css +++ b/skins/base/css/molecules/MessageComposer.css @@ -14,7 +14,71 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_MessageComposer textarea { - width: 100%; +.mx_MessageComposer_wrapper { + max-width: 720px; + height: 50px; + vertical-align: middle; margin: auto; + background-color: #fff; + border-radius: 25px; + border: 1px solid #a9dbf4; +} + +.mx_MessageComposer_row { + display: table-row; + width: 100%; + height: 50px; +} + +.mx_MessageComposer .mx_MessageComposer_avatar { + display: table-cell; + padding-left: 5px; + padding-right: 10px; + height: 50px; +} + +.mx_MessageComposer .mx_MessageComposer_avatar img { + margin-top: 5px; + border-radius: 20px; + background-color: #dbdbdb; +} + +.mx_MessageComposer_input { + display: table-cell; + width: 100%; + vertical-align: middle; + height: 50px; +} + +.mx_MessageComposer_input textarea { + font-size: 15px; + width: 100%; + height: 1.2em; + padding-top: 0.7em; + padding-bottom: 0.7em; + border: 0px; + resize: none; + outline: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + + /* needed for FF */ + font-family: 'Lato', Helvetica, Arial, Sans-Serif; +} + +/* hack for FF as vertical alignment of custom placeholder text is broken */ +.mx_MessageComposer_input textarea::-moz-placeholder { + line-height: 100%; +} + +.mx_MessageComposer_upload { + display: table-cell; + vertical-align: middle; + padding-right: 15px; + cursor: pointer; +} + +.mx_MessageComposer_upload img { + margin-top: 5px; } diff --git a/skins/base/css/molecules/MessageTile.css b/skins/base/css/molecules/MessageTile.css index dae12e1a2b..45882de6dc 100644 --- a/skins/base/css/molecules/MessageTile.css +++ b/skins/base/css/molecules/MessageTile.css @@ -15,11 +15,52 @@ limitations under the License. */ .mx_MessageTile { - display: table-row; + max-width: 100%; + clear: both; + margin-top: 32px; + margin-left: 56px; +} + +.mx_MessageTile_avatar { + padding-left: 12px; + padding-right: 12px; + margin-left: -64px; + margin-top: -7px; + float: left; +} + +.mx_MessageTile_avatar img { + background-color: #dbdbdb; + border-radius: 20px; + border: 0px; +} + +.mx_MessageTile_continuation { + margin-top: 8px ! important; +} + +.mx_MessageTile .mx_SenderProfile { + color: #454545; + opacity: 0.5; + font-size: 14px; + margin-bottom: 4px; + display: block; +} + +.mx_MessageTile .mx_MessageTimestamp { + color: #454545; + opacity: 0.5; + font-size: 14px; + float: right; } .mx_MessageTile_content { - display: table-cell; + padding-right: 100px; + display: block; +} + +.mx_MessageTile_notice .mx_MessageTile_content { + opacity: 0.5; } .mx_MessageTile_sending { @@ -33,3 +74,7 @@ limitations under the License. .mx_MessageTile_highlight { color: #00f; } + +.mx_MessageTile_msgOption { + float: right; +} diff --git a/skins/base/css/molecules/RoomDropTarget.css b/skins/base/css/molecules/RoomDropTarget.css new file mode 100644 index 0000000000..c42d44995d --- /dev/null +++ b/skins/base/css/molecules/RoomDropTarget.css @@ -0,0 +1,27 @@ +/* +Copyright 2015 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. +*/ + +.mx_RoomDropTarget { + font-size: 14px; + text-align: center; + margin-left: 8px; + margin-right: 8px; + padding-top: 16px; + padding-bottom: 16px; + background-color: #fbfbfb; + border: 1px dashed #d7d7d7; + border-radius: 8px; +} diff --git a/skins/base/css/molecules/RoomHeader.css b/skins/base/css/molecules/RoomHeader.css index 63d6fc33fb..6774387726 100644 --- a/skins/base/css/molecules/RoomHeader.css +++ b/skins/base/css/molecules/RoomHeader.css @@ -15,6 +15,125 @@ limitations under the License. */ .mx_RoomHeader { - height: 1em; - padding: 0px; } + +.mx_RoomHeader_wrapper { + max-width: 720px; + margin: auto; + height: 88px; + border-bottom: 1px solid #a8dbf3; + + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +.mx_RoomHeader_leftRow { + height: 48px; + margin-top: 18px; + + -webkit-box-ordinal-group: 1; + -moz-box-ordinal-group: 1; + -ms-flex-order: 1; + -webkit-order: 1; + order: 1; + + width: 100%; +} + +.mx_RoomHeader_hangupButton { + height: 48px; + margin-top: 18px; + background-color: #80cef4; + border-radius: 48px; + margin-right: 8px; + color: #fff; + line-height: 48px; + text-align: center; + + -webkit-box-ordinal-group: 2; + -moz-box-ordinal-group: 2; + -ms-flex-order: 2; + -webkit-order: 2; + order: 2; + + -webkit-flex: 0 0 90px; + flex: 0 0 90px; +} + +.mx_RoomHeader_rightRow { + height: 48px; + margin-top: 18px; + background-color: #fff; + border-radius: 48px; + border: 1px solid #a9dbf4; + + -webkit-box-ordinal-group: 3; + -moz-box-ordinal-group: 3; + -ms-flex-order: 3; + -webkit-order: 3; + order: 3; + + -webkit-flex: 0 0 200px; + flex: 0 0 200px; +} + +.mx_RoomHeader_info { + display: table-cell; + height: 48px; + vertical-align: middle; +} + +.mx_RoomHeader_simpleHeader { + line-height: 88px; + color: #80cef4; + font-weight: 400; + font-size: 20px; + overflow: scroll; + text-overflow: ellipsis; +} + +.mx_RoomHeader_name { + vertical-align: middle; + height: 28px; + color: #80cef4; + font-weight: 400; + font-size: 20px; + padding-left: 16px; + padding-right: 16px; + overflow: scroll; + text-overflow: ellipsis; +} + +.mx_RoomHeader_topic { + vertical-align: bottom; + float: left; + max-height: 38px; + color: #70b5d7; + font-weight: 300; + padding-left: 16px; + padding-right: 16px; + overflow: scroll; + text-overflow: ellipsis; +} + +.mx_RoomHeader_avatar { + display: table-cell; + width: 48px; + height: 50px; + vertical-align: middle; +} + +.mx_RoomHeader_avatar img { + border-radius: 24px; +} + +.mx_RoomHeader_button { + height: 48px; + display: table-cell; + vertical-align: middle; + padding-left: 8px; + padding-right: 8px; +} \ No newline at end of file diff --git a/skins/base/css/molecules/RoomSettings.css b/skins/base/css/molecules/RoomSettings.css new file mode 100644 index 0000000000..53686ec94e --- /dev/null +++ b/skins/base/css/molecules/RoomSettings.css @@ -0,0 +1,34 @@ +/* +Copyright 2015 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. +*/ + +.mx_RoomSettings { + max-height: 250px; +} + +.mx_RoomSettings_settings { + display: table; + margin: 5px 0; +} + +.mx_RoomSettings_settings > div { + display: table-row; +} + +.mx_RoomSettings_settings > div > * { + display: table-cell; + + margin: 0 10px; +} diff --git a/skins/base/css/molecules/RoomTile.css b/skins/base/css/molecules/RoomTile.css index 719551cb57..d43945c377 100644 --- a/skins/base/css/molecules/RoomTile.css +++ b/skins/base/css/molecules/RoomTile.css @@ -15,31 +15,84 @@ limitations under the License. */ .mx_RoomTile { - padding: 5px; cursor: pointer; + display: table-row; + color: #818794; } -.mx_RoomTile.selected { - text-decoration: underline; +.mx_RoomTile_avatar { + display: table-cell; + padding-right: 12px; + padding-top: 3px; + padding-bottom: 3px; + padding-left: 16px; + vertical-align: middle; + width: 40px; + height: 40px; + position: relative; +} + +.mx_RoomTile_avatar img { + border-radius: 20px; + background-color: #dbdbdb; } .mx_RoomTile_name { -} - -.mx_RoomTile div { + display: table-cell; + vertical-align: middle; overflow: hidden; text-overflow: ellipsis; + padding-right: 16px; } -.mx_RoomTile.unread { +/* +.mx_RoomTile_nameBadge { + display: table; + width: 100%; + height: 50px; +} + +.mx_RoomTile_badgeCell { + display: table-cell; + vertical-align: middle; + width: 26px; +} + +.mx_RoomTile_badge { + background-color: #80cef4; + color: #fff; + border-radius: 26px; + font-weight: 400; + font-size: 14px; + line-height: 28px; + width: 26px; + height: 26px; + text-align: center; +} +*/ + +.mx_RoomTile_badge { + background-color: #ff0064; + border: 3px solid #fff; + border-radius: 16px; + width: 9px; + height: 9px; + position: absolute; + right: 9px; + bottom: 3px; +} + +.mx_RoomTile_unread, +.mx_RoomTile_highlight, +.mx_RoomTile_invited +{ font-weight: bold; + color: #000; } -.mx_RoomTile.highlight { - background-color: lime; -} - -.mx_RoomTile.invited { +.mx_RoomTile_selected { + background-color: #f3f8fa; + color: #80cef4; font-weight: bold; } diff --git a/skins/base/css/molecules/SenderProfile.css b/skins/base/css/molecules/SenderProfile.css index 549b598458..18523a9b3f 100644 --- a/skins/base/css/molecules/SenderProfile.css +++ b/skins/base/css/molecules/SenderProfile.css @@ -15,6 +15,4 @@ limitations under the License. */ .mx_SenderProfile { - display: table-cell; - padding: 0px 1em 0em 1em; } diff --git a/skins/base/css/molecules/ServerConfig.css b/skins/base/css/molecules/ServerConfig.css new file mode 100644 index 0000000000..db0572c841 --- /dev/null +++ b/skins/base/css/molecules/ServerConfig.css @@ -0,0 +1,31 @@ +/* +Copyright 2015 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. +*/ + +.mx_ServerConfig { + margin-top: 7px; +} + +.mx_ServerConfig .mx_Login_field { + margin-top: 4px; + margin-bottom: 5px; +} + +.mx_ServerConfig_help:link { + opacity: 0.8; + font-size: 14px; + font-weight: 300; + color: #4a4a4a; +} \ No newline at end of file diff --git a/skins/base/css/molecules/voip/CallView.css b/skins/base/css/molecules/voip/CallView.css new file mode 100644 index 0000000000..01cdb45ae1 --- /dev/null +++ b/skins/base/css/molecules/voip/CallView.css @@ -0,0 +1,15 @@ +/* +Copyright 2015 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. +*/ \ No newline at end of file diff --git a/skins/base/css/molecules/voip/IncomingCallbox.css b/skins/base/css/molecules/voip/IncomingCallbox.css new file mode 100644 index 0000000000..2c57a3273a --- /dev/null +++ b/skins/base/css/molecules/voip/IncomingCallbox.css @@ -0,0 +1,68 @@ +/* +Copyright 2015 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. +*/ + +.mx_IncomingCallBox { + text-align: center; + border: 1px solid #a9dbf4; + border-radius: 8px; + background-color: #fff; + position: absolute; + z-index: 1000; + left: 235px; + top: 155px; + padding: 6px; +} + +.mx_IncomingCallBox_chevron { + padding: 12px; + position: absolute; + left: -21px; + top: 0px; +} + +.mx_IncomingCallBox_title { + padding: 6px; + font-weight: bold; +} + +.mx_IncomingCallBox_buttons { + display: table-row; +} + +.mx_IncomingCallBox_buttons_cell { + vertical-align: middle; + display: table-cell; + padding: 6px; + width: 50%; +} + +.mx_IncomingCallBox_buttons_decline, +.mx_IncomingCallBox_buttons_accept { + vertical-align: middle; + width: 80px; + height: 36px; + line-height: 36px; + border-radius: 36px; + color: #fff; +} + +.mx_IncomingCallBox_buttons_decline { + background-color: #f48080; +} + +.mx_IncomingCallBox_buttons_accept { + background-color: #80f480; +} diff --git a/skins/base/css/molecules/voip/VideoView.css b/skins/base/css/molecules/voip/VideoView.css new file mode 100644 index 0000000000..5edc8504d7 --- /dev/null +++ b/skins/base/css/molecules/voip/VideoView.css @@ -0,0 +1,40 @@ +/* +Copyright 2015 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. +*/ + +.mx_VideoView { + width: 100%; + position: relative; + z-index: 30; + margin-top: 12px; +} + +.mx_VideoView video { + width: 100%; +} + +.mx_VideoView_remoteVideoFeed { + width: 100%; + background-color: #000; + z-index: 50; +} + +.mx_VideoView_localVideoFeed { + width: 20%; + position: absolute; + left: 16px; + bottom: 28px; + z-index: 100; +} \ No newline at end of file diff --git a/skins/base/css/organisms/LeftPanel.css b/skins/base/css/organisms/LeftPanel.css new file mode 100644 index 0000000000..bfc4302655 --- /dev/null +++ b/skins/base/css/organisms/LeftPanel.css @@ -0,0 +1,70 @@ +/* +Copyright 2015 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. +*/ + +.mx_LeftPanel { + position: relative; + + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + flex-direction: column; + -webkit-flex-direction: column; +} + +.mx_LeftPanel_hideButton { + position: absolute; + top: 10px; + right: 10px; +} + +.mx_LeftPanel .mx_RoomList { + -webkit-box-ordinal-group: 1; + -moz-box-ordinal-group: 1; + -ms-flex-order: 1; + -webkit-order: 1; + order: 1; + + height: 100%; + overflow-y: scroll; +} + +.mx_LeftPanel .mx_BottomLeftMenu { + -webkit-box-ordinal-group: 3; + -moz-box-ordinal-group: 3; + -ms-flex-order: 3; + -webkit-order: 3; + order: 3; + + -webkit-flex: 0 0 170px; + flex: 0 0 170px; + + border-top: 1px solid #f3f8fa; +} + +.mx_LeftPanel .mx_BottomLeftMenu .mx_RoomTile { + color: #378bb4; +} + +.mx_LeftPanel .mx_BottomLeftMenu .mx_RoomTile_avatar { + padding-left: 14px; +} + +.mx_LeftPanel .mx_BottomLeftMenu .mx_BottomLeftMenu_options { + margin-top: 12px; + width: 100%; +} \ No newline at end of file diff --git a/skins/base/css/organisms/MemberList.css b/skins/base/css/organisms/MemberList.css new file mode 100644 index 0000000000..b56e3f1180 --- /dev/null +++ b/skins/base/css/organisms/MemberList.css @@ -0,0 +1,47 @@ +/* +Copyright 2015 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. +*/ + +.mx_MemberList { + height: 100%; + margin-bottom: 100px; + padding: 8px; +} + +.mx_MemberList_chevron { + position: absolute; + right: 35px; + margin-top: -15px; +} + +.mx_MemberList_border { + border: 1px solid #a9dbf4; + overflow-y: scroll; + height: auto; + max-height: 75%; + border-radius: 8px; + padding: 20px 14px 14px 24px; + background-color: #fff; +} + +.mx_MemberList_wrapper { + display: table; + table-layout: fixed; + width: 100%; +} + +.mx_MemberList h2 { + margin-top: 0px; +} diff --git a/skins/base/css/organisms/RightPanel.css b/skins/base/css/organisms/RightPanel.css new file mode 100644 index 0000000000..6ee7f6ffdf --- /dev/null +++ b/skins/base/css/organisms/RightPanel.css @@ -0,0 +1,66 @@ +/* +Copyright 2015 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. +*/ + +.mx_RightPanel { + position: relative; + + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + flex-direction: column; + -webkit-flex-direction: column; +} + +.mx_RightPanel_header { + -webkit-box-ordinal-group: 1; + -moz-box-ordinal-group: 1; + -ms-flex-order: 1; + -webkit-order: 1; + order: 1; + + -webkit-flex: 0 0 66px; + flex: 0 0 66px; +} + +/** Fixme - factor this out with the main header **/ + +.mx_RightPanel_headerButtonGroup { + margin-top: 18px; + height: 48px; + float: right; + background-color: #fff; + border-radius: 48px; + border: 1px solid #a9dbf4; + margin-right: 22px; +} + +.mx_RightPanel_headerButton { + height: 48px; + display: table-cell; + vertical-align: middle; + padding-left: 8px; + padding-right: 8px; +} + +.mx_RightPanel .mx_MemberList { + -webkit-box-ordinal-group: 2; + -moz-box-ordinal-group: 2; + -ms-flex-order: 2; + -webkit-order: 2; + order: 2; +} diff --git a/skins/base/css/organisms/RoomDirectory.css b/skins/base/css/organisms/RoomDirectory.css new file mode 100644 index 0000000000..1be87c1f42 --- /dev/null +++ b/skins/base/css/organisms/RoomDirectory.css @@ -0,0 +1,41 @@ +/* +Copyright 2015 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. +*/ + +.mx_RoomDirectory { + width: 720px; + margin-left: auto; + margin-right: auto; +} + +.mx_RoomDirectory_input { + margin: auto; + border-radius: 3px; + border: 1px solid #c7c7c7; + font-weight: 300; + font-size: 14px; + padding: 9px; + margin-top: 12px; + margin-bottom: 12px; +} + +.mx_RoomDirectory_table { + width: 100%; +} + +.mx_RoomDirectory_table td, +.mx_RoomDirectory_table th, { + padding: 6px; +} \ No newline at end of file diff --git a/skins/base/css/organisms/RoomList.css b/skins/base/css/organisms/RoomList.css index e2dec3c9fd..35978e5be3 100644 --- a/skins/base/css/organisms/RoomList.css +++ b/skins/base/css/organisms/RoomList.css @@ -16,3 +16,15 @@ limitations under the License. .mx_RoomList { } + +.mx_RoomList_recents { + margin-top: -12px; + display: table; + table-layout: fixed; + width: 100%; +} + +.mx_RoomList h2 { + padding-left: 16px; + padding-right: 16px; +} \ No newline at end of file diff --git a/skins/base/css/organisms/RoomView.css b/skins/base/css/organisms/RoomView.css index 4176c4b8cc..f860b23ef9 100644 --- a/skins/base/css/organisms/RoomView.css +++ b/skins/base/css/organisms/RoomView.css @@ -17,66 +17,132 @@ limitations under the License. .mx_RoomView { word-wrap: break-word; position: relative; -} -.mx_RoomView .mx_RoomHeader { - height: 30px; -} - -.mx_RoomView_roomWrapper { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; - display: flex; - position: absolute; + display: flex; width: 100%; - top: 32px; - bottom: 0px; + + flex-direction: column; + -webkit-flex-direction: column; } -.mx_RoomView_messagePanel { +.mx_RoomView .mx_RoomHeader { -webkit-box-ordinal-group: 1; -moz-box-ordinal-group: 1; -ms-flex-order: 1; -webkit-order: 1; order: 1; - width: 100%; - height: 100%; - /* background-color: #ff0; */ + + -webkit-flex: 0 0 88px; + flex: 0 0 88px; } -.mx_RoomView_messageListWrapper { - height: 100%; - overflow-y: scroll; -} - -.mx_RoomView_MessageList { - display: table; -} - -.mx_RoomView_invitePrompt { -} - -.mx_RoomView .mx_MemberList { +.mx_RoomView_auxPanel { -webkit-box-ordinal-group: 2; -moz-box-ordinal-group: 2; -ms-flex-order: 2; -webkit-order: 2; order: 2; - /* background-color: #0f0; */ - width: 250px; - overflow-y: scroll; - height: 100%; + max-width: 720px; + width: 100%; + margin: auto; + + overflow: scroll; + -webkit-flex: 0 0 auto; + flex: 0 0 auto; } -.mx_RoomView .mx_MemberList ul { - margin: 0px; - padding: 0px; +.mx_RoomView_messagePanel { + -webkit-box-ordinal-group: 3; + -moz-box-ordinal-group: 3; + -ms-flex-order: 3; + -webkit-order: 3; + order: 3; + + width: 100%; + flex: 1 1 0; + margin-top: 18px; + margin-bottom: 18px; + + overflow-y: scroll; +} + +.mx_RoomView_messageListWrapper { + max-width: 720px; + margin: auto; +} + +.mx_RoomView_MessageList { + width: 100%; +} + +.mx_RoomView_MessageList h2 { + clear: both; + margin-top: 32px; + margin-bottom: 8px; + padding-bottom: 6px; + border-bottom: 1px solid #a8dbf3; +} + +.mx_RoomView_invitePrompt { +} + +.mx_RoomView_statusArea { + -webkit-box-ordinal-group: 4; + -moz-box-ordinal-group: 4; + -ms-flex-order: 4; + -webkit-order: 4; + order: 4; + + width: 100%; + -webkit-flex: 0 0 58px; + flex: 0 0 58px; +} + +.mx_RoomView_statusAreaBox { + max-width: 720px; + margin: auto; + border-top: 1px solid #a8dbf3; +} + +.mx_RoomView_typingBar { + margin-top: 17px; + margin-left: 56px; + color: #818794; +} + +.mx_RoomView_typingBar img { + padding-left: 12px; + padding-right: 12px; + margin-left: -64px; + margin-top: -7px; + float: left; } .mx_RoomView .mx_MessageComposer { + -webkit-box-ordinal-group: 5; + -moz-box-ordinal-group: 5; + -ms-flex-order: 5; + -webkit-order: 5; + order: 5; + width: 100%; - bottom: 0px; + -webkit-flex: 0 0 63px; + flex: 0 0 63px; + margin-right: 2px; +} + +.mx_RoomView_uploadProgressOuter { + width: 100%; + background-color: black; + height: 5px; +} + +.mx_RoomView_uploadProgressInner { + background-color: blue; + height: 5px; } diff --git a/skins/base/css/organisms/UserSettings.css b/skins/base/css/organisms/UserSettings.css new file mode 100644 index 0000000000..b69399b72b --- /dev/null +++ b/skins/base/css/organisms/UserSettings.css @@ -0,0 +1,21 @@ +/* +Copyright 2015 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. +*/ + +.mx_UserSettings { + width: 720px; + margin-left: auto; + margin-right: auto; +} diff --git a/skins/base/css/pages/MatrixChat.css b/skins/base/css/pages/MatrixChat.css index 7ce88ec7ff..7ac51b56a4 100644 --- a/skins/base/css/pages/MatrixChat.css +++ b/skins/base/css/pages/MatrixChat.css @@ -14,76 +14,101 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_MatrixChat { - position: relative; - width: 100%; - height: 100%; -} - -.mx_MatrixChat_chatWrapper { +.mx_MatrixChat_wrapper { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; - display: flex; - position: absolute; - width: 100%; - top: 0px; - bottom: 42px; -} + display: flex; -.mx_MatrixChat_leftPanel { - -webkit-box-ordinal-group: 1; - -moz-box-ordinal-group: 1; - -ms-flex-order: 1; - -webkit-order: 1; - order: 1; - - display: -webkit-box; - display: -moz-box; - display: -ms-flexbox; - display: -webkit-flex; - display: flex; flex-direction: column; -webkit-flex-direction: column; - /* background-color: #f00; */ - width: 250px; + width: 100%; height: 100%; } -.mx_MatrixChat_leftPanel .mx_MatrixToolbar { +.mx_MatrixToolbar { -webkit-box-ordinal-group: 1; -moz-box-ordinal-group: 1; -ms-flex-order: 1; -webkit-order: 1; order: 1; - width: 100%; - height: 40px; + height: 21px; } -.mx_MatrixChat_leftPanel .mx_RoomList { - -webkit-box-ordinal-group: 2; - -moz-box-ordinal-group: 2; - -ms-flex-order: 2; - -webkit-order: 2; - order: 2; +.mx_MatrixChat_toolbarShowing { + height: auto; +} - /* background-color: #0ff; */ +.mx_MatrixChat { width: 100%; height: 100%; - overflow-y: scroll; -} -.mx_MatrixChat .mx_RoomView { + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-ordinal-group: 2; -moz-box-ordinal-group: 2; -ms-flex-order: 2; -webkit-order: 2; order: 2; - /* background-color: #00f; */ - width: 100%; - height: 100%; + -webkit-flex: 1; + flex: 1; +} + +.mx_MatrixChat .mx_LeftPanel { + -webkit-box-ordinal-group: 1; + -moz-box-ordinal-group: 1; + -ms-flex-order: 1; + -webkit-order: 1; + order: 1; + + -webkit-flex: 0 0 230px; + flex: 0 0 230px; +} + +.mx_MatrixChat .mx_MatrixChat_middlePanel { + -webkit-box-ordinal-group: 2; + -moz-box-ordinal-group: 2; + -ms-flex-order: 2; + -webkit-order: 2; + order: 2; + + padding-left: 12px; + padding-right: 12px; + background-color: #f3f8fa; + width: 100%; + + /* XXX: Hack: apparently if you try to nest a flex-box + * within a non-flex-box within a flex-box, the height + * of the innermost element gets miscalculated if the + * parents are both auto. + * Ideally we'd launch straight into the RoomView at this + * point, but instead we fudge it and make the middlePanel + * flex itself. + */ + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +.mx_MatrixChat .mx_RightPanel { + -webkit-box-ordinal-group: 3; + -moz-box-ordinal-group: 3; + -ms-flex-order: 3; + -webkit-order: 3; + order: 3; + + background-color: #f3f8fa; + -webkit-flex: 0 0 230px; + flex: 0 0 230px; + height: 100%; } diff --git a/skins/base/css/templates/Login.css b/skins/base/css/templates/Login.css index 7dbcde1caa..fe5646f9d3 100644 --- a/skins/base/css/templates/Login.css +++ b/skins/base/css/templates/Login.css @@ -15,8 +15,81 @@ limitations under the License. */ .mx_Login { - width: 600px; - height: 350px; - position: relative; + width: 100%; + height: 100%; + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + -webkit-justify-content: center; + justify-content: center; +} + +.mx_Login h2 { + color: #4a4a4a; + font-weight: 300; + margin-top: 32px; + margin-bottom: 20px; +} + +.mx_Login_box { + width: 300px; +} + +.mx_Login_logo { + text-align: center; +} + +.mx_Login_field { + width: 100%; + border-radius: 3px; + border: 1px solid #c7c7c7; + font-weight: 300; + font-size: 14px; + padding: 9px; + margin-bottom: 14px; +} + +.mx_Login_submit { + margin-top: 35px; + margin-bottom: 24px; + width: 100%; + border-radius: 40px; + height: 40px; + border: 0px; + background-color: #76cfa6; + font-size: 16px; + color: #fff; +} + +.mx_Login_label { + font-size: 14px; + opacity: 0.8; +} + +.mx_Login_checkbox { + margin-right: 10px; +} + +.mx_Login_create { + display: block; + text-align: center; + width: 100%; + font-size: 14px; + opacity: 0.8; +} + +.mx_Login_error { + color: #ff2020; + font-weight: bold; + text-align: center; + margin-bottom: 24px; +} + +.mx_Login_create:link { + color: #4a4a4a; } diff --git a/skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 b/skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 new file mode 100644 index 0000000000..8c49ba2aa7 Binary files /dev/null and b/skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 differ diff --git a/skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 b/skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 new file mode 100644 index 0000000000..24217a1f97 Binary files /dev/null and b/skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 differ diff --git a/skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 b/skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 new file mode 100644 index 0000000000..890fc5fb46 Binary files /dev/null and b/skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 differ diff --git a/skins/base/fonts/Lato.css b/skins/base/fonts/Lato.css new file mode 100644 index 0000000000..e3e3115daf --- /dev/null +++ b/skins/base/fonts/Lato.css @@ -0,0 +1,48 @@ +/* latin-ext */ +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 300; + src: local('Lato Light'), local('Lato-Light'), url(IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 300; + src: local('Lato Light'), local('Lato-Light'), url(22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; +} +/* latin-ext */ +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 400; + src: local('Lato Regular'), local('Lato-Regular'), url(8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 400; + src: local('Lato Regular'), local('Lato-Regular'), url(MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; +} +/* latin-ext */ +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 700; + src: local('Lato Bold'), local('Lato-Bold'), url(rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Lato'; + font-style: normal; + font-weight: 700; + src: local('Lato Bold'), local('Lato-Bold'), url(MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; +} diff --git a/skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2 b/skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2 new file mode 100644 index 0000000000..c83fe95542 Binary files /dev/null and b/skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2 differ diff --git a/skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 b/skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 new file mode 100644 index 0000000000..a9ffeae995 Binary files /dev/null and b/skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 differ diff --git a/skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 b/skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 new file mode 100644 index 0000000000..272e1ea8e5 Binary files /dev/null and b/skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 differ diff --git a/skins/base/img/attach.png b/skins/base/img/attach.png new file mode 100644 index 0000000000..1bcb70045d Binary files /dev/null and b/skins/base/img/attach.png differ diff --git a/skins/base/img/chevron-left.png b/skins/base/img/chevron-left.png new file mode 100644 index 0000000000..12abcc264b Binary files /dev/null and b/skins/base/img/chevron-left.png differ diff --git a/skins/base/img/chevron-right.png b/skins/base/img/chevron-right.png new file mode 100644 index 0000000000..1fe5d347db Binary files /dev/null and b/skins/base/img/chevron-right.png differ diff --git a/skins/base/img/chevron.png b/skins/base/img/chevron.png new file mode 100644 index 0000000000..3df8655bcf Binary files /dev/null and b/skins/base/img/chevron.png differ diff --git a/skins/base/img/create-big.png b/skins/base/img/create-big.png new file mode 100644 index 0000000000..9c4627b1a1 Binary files /dev/null and b/skins/base/img/create-big.png differ diff --git a/skins/base/img/create.png b/skins/base/img/create.png new file mode 100644 index 0000000000..2d6107ac50 Binary files /dev/null and b/skins/base/img/create.png differ diff --git a/skins/base/img/directory-big.png b/skins/base/img/directory-big.png new file mode 100644 index 0000000000..fb2bc388be Binary files /dev/null and b/skins/base/img/directory-big.png differ diff --git a/skins/base/img/file.png b/skins/base/img/file.png new file mode 100644 index 0000000000..5904ea8284 Binary files /dev/null and b/skins/base/img/file.png differ diff --git a/skins/base/img/filegrid.png b/skins/base/img/filegrid.png new file mode 100644 index 0000000000..c2c2799f37 Binary files /dev/null and b/skins/base/img/filegrid.png differ diff --git a/skins/base/img/filelist.png b/skins/base/img/filelist.png new file mode 100644 index 0000000000..3cf6cb494e Binary files /dev/null and b/skins/base/img/filelist.png differ diff --git a/skins/base/img/hide.png b/skins/base/img/hide.png new file mode 100644 index 0000000000..3e64618b09 Binary files /dev/null and b/skins/base/img/hide.png differ diff --git a/skins/base/img/info.png b/skins/base/img/info.png new file mode 100644 index 0000000000..699fd64e01 Binary files /dev/null and b/skins/base/img/info.png differ diff --git a/skins/base/img/logo.png b/skins/base/img/logo.png new file mode 100644 index 0000000000..7cea081a8f Binary files /dev/null and b/skins/base/img/logo.png differ diff --git a/skins/base/img/members.png b/skins/base/img/members.png new file mode 100644 index 0000000000..6526f2362e Binary files /dev/null and b/skins/base/img/members.png differ diff --git a/skins/base/img/menu.png b/skins/base/img/menu.png new file mode 100644 index 0000000000..3550878bf2 Binary files /dev/null and b/skins/base/img/menu.png differ diff --git a/skins/base/img/p/p0.png b/skins/base/img/p/p0.png new file mode 100644 index 0000000000..300cc22654 Binary files /dev/null and b/skins/base/img/p/p0.png differ diff --git a/skins/base/img/p/p1.png b/skins/base/img/p/p1.png new file mode 100644 index 0000000000..5a6e3054e4 Binary files /dev/null and b/skins/base/img/p/p1.png differ diff --git a/skins/base/img/p/p10.png b/skins/base/img/p/p10.png new file mode 100644 index 0000000000..7cead0f239 Binary files /dev/null and b/skins/base/img/p/p10.png differ diff --git a/skins/base/img/p/p11.png b/skins/base/img/p/p11.png new file mode 100644 index 0000000000..d744d8af2f Binary files /dev/null and b/skins/base/img/p/p11.png differ diff --git a/skins/base/img/p/p12.png b/skins/base/img/p/p12.png new file mode 100644 index 0000000000..02492d554a Binary files /dev/null and b/skins/base/img/p/p12.png differ diff --git a/skins/base/img/p/p13.png b/skins/base/img/p/p13.png new file mode 100644 index 0000000000..0ae8029d87 Binary files /dev/null and b/skins/base/img/p/p13.png differ diff --git a/skins/base/img/p/p14.png b/skins/base/img/p/p14.png new file mode 100644 index 0000000000..23a3840bf8 Binary files /dev/null and b/skins/base/img/p/p14.png differ diff --git a/skins/base/img/p/p15.png b/skins/base/img/p/p15.png new file mode 100644 index 0000000000..b07f463a07 Binary files /dev/null and b/skins/base/img/p/p15.png differ diff --git a/skins/base/img/p/p16.png b/skins/base/img/p/p16.png new file mode 100644 index 0000000000..f8fa4abfa1 Binary files /dev/null and b/skins/base/img/p/p16.png differ diff --git a/skins/base/img/p/p17.png b/skins/base/img/p/p17.png new file mode 100644 index 0000000000..20e985bb1c Binary files /dev/null and b/skins/base/img/p/p17.png differ diff --git a/skins/base/img/p/p18.png b/skins/base/img/p/p18.png new file mode 100644 index 0000000000..2ecd29b350 Binary files /dev/null and b/skins/base/img/p/p18.png differ diff --git a/skins/base/img/p/p19.png b/skins/base/img/p/p19.png new file mode 100644 index 0000000000..ec35f0fc80 Binary files /dev/null and b/skins/base/img/p/p19.png differ diff --git a/skins/base/img/p/p2.png b/skins/base/img/p/p2.png new file mode 100644 index 0000000000..82f16d6078 Binary files /dev/null and b/skins/base/img/p/p2.png differ diff --git a/skins/base/img/p/p20.png b/skins/base/img/p/p20.png new file mode 100644 index 0000000000..0ff816d61b Binary files /dev/null and b/skins/base/img/p/p20.png differ diff --git a/skins/base/img/p/p3.png b/skins/base/img/p/p3.png new file mode 100644 index 0000000000..ae215557a8 Binary files /dev/null and b/skins/base/img/p/p3.png differ diff --git a/skins/base/img/p/p4.png b/skins/base/img/p/p4.png new file mode 100644 index 0000000000..011ff6f541 Binary files /dev/null and b/skins/base/img/p/p4.png differ diff --git a/skins/base/img/p/p5.png b/skins/base/img/p/p5.png new file mode 100644 index 0000000000..1a90da9aac Binary files /dev/null and b/skins/base/img/p/p5.png differ diff --git a/skins/base/img/p/p6.png b/skins/base/img/p/p6.png new file mode 100644 index 0000000000..453110f62f Binary files /dev/null and b/skins/base/img/p/p6.png differ diff --git a/skins/base/img/p/p7.png b/skins/base/img/p/p7.png new file mode 100644 index 0000000000..6418817ca8 Binary files /dev/null and b/skins/base/img/p/p7.png differ diff --git a/skins/base/img/p/p8.png b/skins/base/img/p/p8.png new file mode 100644 index 0000000000..0e821fd675 Binary files /dev/null and b/skins/base/img/p/p8.png differ diff --git a/skins/base/img/p/p9.png b/skins/base/img/p/p9.png new file mode 100644 index 0000000000..f4b6941b24 Binary files /dev/null and b/skins/base/img/p/p9.png differ diff --git a/skins/base/img/p/piechart.pde b/skins/base/img/p/piechart.pde new file mode 100644 index 0000000000..44fe628378 --- /dev/null +++ b/skins/base/img/p/piechart.pde @@ -0,0 +1,19 @@ +// a trivial processing.org snippet to generate these +// using java2d (ugh). Peity and JS might have been +// a better idea. Or SVG. + +size(48, 48); +g = createGraphics(48, 48, JAVA2D); + +for (int i = 0; i <= 20; i++) { + g.beginDraw(); + g.background(0.0, 0.0); + g.smooth(); + g.strokeCap(SQUARE); + g.strokeWeight(3); + g.stroke(0x80, 0xcf, 0xf4, 255.0); + g.fill(0.0, 0.0); + g.arc(24, 24, 43, 43, -PI/2, -PI/2 + (i*2*PI/20.0)); + g.save("p" + i + ".png"); + g.endDraw(); +} diff --git a/skins/base/img/placeholder.png b/skins/base/img/placeholder.png new file mode 100644 index 0000000000..7da32f259c Binary files /dev/null and b/skins/base/img/placeholder.png differ diff --git a/skins/base/img/search.png b/skins/base/img/search.png new file mode 100644 index 0000000000..d2c99855d0 Binary files /dev/null and b/skins/base/img/search.png differ diff --git a/skins/base/img/settings-big.png b/skins/base/img/settings-big.png new file mode 100644 index 0000000000..663ca16315 Binary files /dev/null and b/skins/base/img/settings-big.png differ diff --git a/skins/base/img/settings.png b/skins/base/img/settings.png new file mode 100644 index 0000000000..445a3909e4 Binary files /dev/null and b/skins/base/img/settings.png differ diff --git a/skins/base/img/typing.png b/skins/base/img/typing.png new file mode 100644 index 0000000000..066a0ce8fd Binary files /dev/null and b/skins/base/img/typing.png differ diff --git a/skins/base/img/upload.png b/skins/base/img/upload.png new file mode 100644 index 0000000000..428501f00f Binary files /dev/null and b/skins/base/img/upload.png differ diff --git a/skins/base/img/video.png b/skins/base/img/video.png new file mode 100644 index 0000000000..2a788f6fa4 Binary files /dev/null and b/skins/base/img/video.png differ diff --git a/skins/base/img/voip.png b/skins/base/img/voip.png new file mode 100644 index 0000000000..e8f05bcc37 Binary files /dev/null and b/skins/base/img/voip.png differ diff --git a/skins/base/views/atoms/EditableText.js b/skins/base/views/atoms/EditableText.js index a8f55814e7..38aa5c8d87 100644 --- a/skins/base/views/atoms/EditableText.js +++ b/skins/base/views/atoms/EditableText.js @@ -33,6 +33,7 @@ module.exports = React.createClass({ }, onClickDiv: function() { + console.log("onClickDiv triggered"); this.setState({ phase: this.Phases.Edit, }) @@ -43,18 +44,26 @@ module.exports = React.createClass({ }, onFinish: function(ev) { - this.setValue(ev.target.value); + if (ev.target.value) { + this.setValue(ev.target.value, ev.key === "Enter"); + } else { + this.cancelEdit(); + } }, render: function() { var editable_el; if (this.state.phase == this.Phases.Display) { - editable_el =
{this.state.value}
; + if (this.state.value) { + editable_el =
{this.state.value}
; + } else { + editable_el =
{this.props.label}
; + } } else if (this.state.phase == this.Phases.Edit) { editable_el = (
- +
); } diff --git a/skins/base/views/atoms/create_room/Presets.js b/skins/base/views/atoms/create_room/Presets.js index 83fe61bdbb..271702b18a 100644 --- a/skins/base/views/atoms/create_room/Presets.js +++ b/skins/base/views/atoms/create_room/Presets.js @@ -25,14 +25,15 @@ module.exports = React.createClass({ mixins: [PresetsController], onValueChanged: function(ev) { - this.setState({preset: ev.target.value}) + this.props.onChange(ev.target.value) }, render: function() { return ( - + + + ); } diff --git a/skins/base/views/atoms/create_room/RoomAlias.js b/skins/base/views/atoms/create_room/RoomAlias.js new file mode 100644 index 0000000000..a59a8e69ad --- /dev/null +++ b/skins/base/views/atoms/create_room/RoomAlias.js @@ -0,0 +1,79 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var React = require('react'); + +var RoomAliasController = require("../../../../../src/controllers/atoms/create_room/RoomAlias"); + +module.exports = React.createClass({ + displayName: 'RoomAlias', + mixins: [RoomAliasController], + + onValueChanged: function(ev) { + this.props.onChange(ev.target.value); + }, + + onFocus: function(ev) { + var target = ev.target; + var curr_val = ev.target.value; + + if (this.props.homeserver) { + if (curr_val == "") { + setTimeout(function() { + target.value = "#:" + this.props.homeserver; + target.setSelectionRange(1, 1); + }, 0); + } else { + var suffix = ":" + this.props.homeserver; + setTimeout(function() { + target.setSelectionRange( + curr_val.startsWith("#") ? 1 : 0, + curr_val.endsWith(suffix) ? (target.value.length - suffix.length) : target.value.length + ); + }, 0); + } + } + }, + + onBlur: function(ev) { + var curr_val = ev.target.value; + + if (this.props.homeserver) { + if (curr_val == "#:" + this.props.homeserver) { + ev.target.value = ""; + return; + } + + if (curr_val != "") { + var new_val = ev.target.value; + var suffix = ":" + this.props.homeserver; + if (!curr_val.startsWith("#")) new_val = "#" + new_val; + if (!curr_val.endsWith(suffix)) new_val = new_val + suffix; + ev.target.value = new_val; + } + } + }, + + render: function() { + return ( + + ); + } +}); diff --git a/skins/base/views/atoms/create_room/RoomNameTextbox.js b/skins/base/views/atoms/voip/VideoFeed.js similarity index 63% rename from skins/base/views/atoms/create_room/RoomNameTextbox.js rename to skins/base/views/atoms/voip/VideoFeed.js index c358a14cb3..7fbee43699 100644 --- a/skins/base/views/atoms/create_room/RoomNameTextbox.js +++ b/skins/base/views/atoms/voip/VideoFeed.js @@ -18,19 +18,17 @@ limitations under the License. var React = require('react'); -var RoomNameTextboxController = require("../../../../../src/controllers/atoms/create_room/RoomNameTextbox"); +var VideoFeedController = require("../../../../../src/controllers/atoms/voip/VideoFeed"); module.exports = React.createClass({ - displayName: 'RoomNameTextbox', - mixins: [RoomNameTextboxController], - - onValueChanged: function(ev) { - this.setState({room_name: ev.target.value}) - }, + displayName: 'VideoFeed', + mixins: [VideoFeedController], render: function() { return ( - + ); - } + }, }); + diff --git a/skins/base/views/molecules/BottomLeftMenu.js b/skins/base/views/molecules/BottomLeftMenu.js new file mode 100644 index 0000000000..d2340d7bfa --- /dev/null +++ b/skins/base/views/molecules/BottomLeftMenu.js @@ -0,0 +1,67 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var React = require('react'); +var classNames = require('classnames'); + +var dis = require("../../../../src/dispatcher"); + +var MatrixClientPeg = require("../../../../src/MatrixClientPeg"); + +module.exports = React.createClass({ + displayName: 'BottomLeftMenu', + + onSettingsClick: function() { + dis.dispatch({action: 'view_user_settings'}); + }, + + onRoomDirectoryClick: function() { + dis.dispatch({action: 'view_room_directory'}); + }, + + onCreateRoomClick: function() { + dis.dispatch({action: 'view_create_room'}); + }, + + render: function() { + return ( +
+
+
+
+ +
+
Create new room
+
+
+
+ +
+
Directory
+
+
+
+ +
+
Settings
+
+
+
+ ); + } +}); diff --git a/skins/base/views/molecules/ChangeAvatar.js b/skins/base/views/molecules/ChangeAvatar.js new file mode 100644 index 0000000000..e70da3a703 --- /dev/null +++ b/skins/base/views/molecules/ChangeAvatar.js @@ -0,0 +1,65 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var React = require('react'); + +var ChangeAvatarController = require("../../../../src/controllers/molecules/ChangeAvatar"); + +var Loader = require("react-loader"); + + +module.exports = React.createClass({ + displayName: 'ChangeAvatar', + mixins: [ChangeAvatarController], + + onFileSelected: function(ev) { + this.setAvatarFromFile(ev.target.files[0]); + }, + + onError: function(error) { + this.setState({ + errorText: "Failed to upload profile picture!" + }); + }, + + render: function() { + switch (this.state.phase) { + case this.Phases.Display: + case this.Phases.Error: + return ( +
+
+ +
+
+ Upload new: + + {this.state.errorText} +
+
+ +
+
+ ); + case this.Phases.Uploading: + return ( + + ); + } + } +}); diff --git a/skins/base/views/molecules/ChangePassword.js b/skins/base/views/molecules/ChangePassword.js new file mode 100644 index 0000000000..2f92f9ab3f --- /dev/null +++ b/skins/base/views/molecules/ChangePassword.js @@ -0,0 +1,85 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var React = require('react'); + +var ChangePasswordController = require("../../../../src/controllers/molecules/ChangePassword"); +var Loader = require("react-loader"); + + +module.exports = React.createClass({ + displayName: 'ChangePassword', + mixins: [ChangePasswordController], + + onClickChange: function() { + var old_password = this.refs.old_input.getDOMNode().value; + var new_password = this.refs.new_input.getDOMNode().value; + var confirm_password = this.refs.confirm_input.getDOMNode().value; + if (new_password != confirm_password) { + this.setState({ + state: this.Phases.Error, + errorString: "Passwords don't match" + }); + } else if (new_password == '' || old_password == '') { + this.setState({ + state: this.Phases.Error, + errorString: "Passwords can't be empty" + }); + } else { + this.changePassword(old_password, new_password); + } + }, + + render: function() { + switch (this.state.phase) { + case this.Phases.Edit: + case this.Phases.Error: + return ( +
+
+
{this.state.errorString}
+
+
+
+
+
+ + +
+
+ ); + case this.Phases.Uploading: + return ( +
+ +
+ ); + case this.Phases.Success: + return ( +
+
+ Success! +
+
+ +
+
+ ) + } + } +}); diff --git a/skins/base/views/molecules/DateSeparator.js b/skins/base/views/molecules/DateSeparator.js new file mode 100644 index 0000000000..061ce66daf --- /dev/null +++ b/skins/base/views/molecules/DateSeparator.js @@ -0,0 +1,56 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var React = require('react'); + +var days = [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" +]; + +module.exports = React.createClass({ + displayName: 'DateSeparator', + render: function() { + var date = new Date(this.props.ts); + var today = new Date(); + var yesterday = new Date(); + yesterday.setDate(today.getDate() - 1); + var label; + if (date.toDateString() === today.toDateString()) { + label = "Today"; + } + else if (date.toDateString() === yesterday.toDateString()) { + label = "Yesterday"; + } + else if (today.getTime() - date.getTime() < 6 * 24 * 60 * 60 * 1000) { + label = days[date.getDay()]; + } + else { + label = date.toDateString(); + } + + return ( +

{ label }

+ ); + } +}); diff --git a/skins/base/views/molecules/EventAsTextTile.js b/skins/base/views/molecules/EventAsTextTile.js new file mode 100644 index 0000000000..f53d83c6d7 --- /dev/null +++ b/skins/base/views/molecules/EventAsTextTile.js @@ -0,0 +1,48 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var React = require('react'); + +var MatrixClientPeg = require("../../../../src/MatrixClientPeg"); +var EventAsTextTileController = require("../../../../src/controllers/molecules/EventAsTextTile"); +var ComponentBroker = require('../../../../src/ComponentBroker'); +var MessageTimestamp = ComponentBroker.get('atoms/MessageTimestamp'); +var TextForEvent = require("../../../../src/TextForEvent"); + +module.exports = React.createClass({ + displayName: 'EventAsTextTile', + mixins: [EventAsTextTileController], + + render: function() { + var text = TextForEvent.textForEvent(this.props.mxEvent); + var timestamp = this.props.last ? : null; + return ( +
+
+ +
+ { timestamp } + + + {TextForEvent.textForEvent(this.props.mxEvent)} + +
+ ); + }, +}); + diff --git a/skins/base/views/molecules/MEmoteTile.js b/skins/base/views/molecules/MEmoteTile.js index e7720e160b..1125a307f5 100644 --- a/skins/base/views/molecules/MEmoteTile.js +++ b/skins/base/views/molecules/MEmoteTile.js @@ -29,7 +29,7 @@ module.exports = React.createClass({ var content = mxEvent.getContent(); var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); return ( - + * {name} {content.body} ); diff --git a/skins/base/views/molecules/MRoomMemberTile.js b/skins/base/views/molecules/MRoomMemberTile.js index f0755e2614..3ca1428316 100644 --- a/skins/base/views/molecules/MRoomMemberTile.js +++ b/skins/base/views/molecules/MRoomMemberTile.js @@ -20,7 +20,9 @@ var React = require('react'); var MRoomMemberTileController = require("../../../../src/controllers/molecules/MRoomMemberTile"); +var MatrixClientPeg = require("../../../../src/MatrixClientPeg"); var ComponentBroker = require('../../../../src/ComponentBroker'); +var TextForEvent = require('../../../../src/TextForEvent'); var MessageTimestamp = ComponentBroker.get('atoms/MessageTimestamp'); module.exports = React.createClass({ @@ -28,27 +30,23 @@ module.exports = React.createClass({ mixins: [MRoomMemberTileController], getMemberEventText: function() { - var ev = this.props.mxEvent; - // XXX: SYJS-16 - var senderName = ev.sender ? ev.sender.name : "Someone"; - switch (ev.getContent().membership) { - case 'invite': - return senderName + " invited " + ev.target.name + "."; - case 'join': - return senderName + " joined the room."; - case 'leave': - return senderName + " left the room."; - } + return TextForEvent.textForEvent(this.props.mxEvent); }, render: function() { // XXX: for now, just cheekily borrow the css from message tile... + var timestamp = this.props.last ? : null; + var text = this.getMemberEventText(); + if (!text) return
; return ( -
- +
+
+ +
+ { timestamp } - {this.getMemberEventText()} + { text }
); diff --git a/skins/base/views/molecules/MatrixToolbar.js b/skins/base/views/molecules/MatrixToolbar.js index e4444ee9c8..c8b4c97cdc 100644 --- a/skins/base/views/molecules/MatrixToolbar.js +++ b/skins/base/views/molecules/MatrixToolbar.js @@ -32,8 +32,7 @@ module.exports = React.createClass({ render: function() { return (
- - + You are not receiving desktop notifications.
); } diff --git a/skins/base/views/molecules/MemberInfo.js b/skins/base/views/molecules/MemberInfo.js new file mode 100644 index 0000000000..8e1e383f69 --- /dev/null +++ b/skins/base/views/molecules/MemberInfo.js @@ -0,0 +1,120 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var React = require('react'); + +var MatrixClientPeg = require("../../../../src/MatrixClientPeg"); +var MemberInfoController = require("../../../../src/controllers/molecules/MemberInfo"); + +module.exports = React.createClass({ + displayName: 'MemberInfo', + mixins: [MemberInfoController], + + componentDidMount: function() { + var self = this; + + var memberInfo = this.getDOMNode(); + var memberListScroll = document.getElementsByClassName("mx_MemberList_border")[0]; + if (memberListScroll) { + memberInfo.style.top = (memberInfo.parentElement.offsetTop - memberListScroll.scrollTop) + "px"; + } + }, + + getDuration: function(time) { + if (!time) return; + var t = parseInt(time / 1000); + var s = t % 60; + var m = parseInt(t / 60) % 60; + var h = parseInt(t / (60 * 60)) % 24; + var d = parseInt(t / (60 * 60 * 24)); + if (t < 60) { + if (t < 0) { + return "0s"; + } + return s + "s"; + } + if (t < 60 * 60) { + return m + "m"; + } + if (t < 24 * 60 * 60) { + return h + "h"; + } + return d + "d "; + }, + + render: function() { + var power; + if (this.props.member) { + var img = "img/p/p" + Math.floor(20 * this.props.member.powerLevelNorm / 100) + ".png"; + power = ; + } + var activeAgo = "unknown"; + if (this.state.active >= 0) { + activeAgo = this.getDuration(this.state.active); + } + var kickButton, banButton, muteButton, giveModButton; + if (this.state.can.kick) { + kickButton =
+ Kick +
; + } + if (this.state.can.ban) { + banButton =
+ Ban +
; + } + if (this.state.can.mute) { + var muteLabel = this.state.muted ? "Unmute" : "Mute"; + muteButton =
+ {muteLabel} +
; + } + if (this.state.can.modifyLevel) { + var giveOpLabel = this.state.isTargetMod ? "Revoke Mod" : "Make Mod"; + giveModButton =
+ {giveOpLabel} +
+ } + + var opLabel; + if (this.state.isTargetMod) { + var level = this.props.member.powerLevelNorm + "%"; + opLabel =
Moderator ({level})
+ } + return ( +
+ +
+
+ +
+
{this.props.member.userId}
+ {opLabel} +
Presence: {this.state.presence}
+
Last active: {activeAgo}
+
Start chat
+ {muteButton} + {kickButton} + {banButton} + {giveModButton} +
+ ); + } +}); diff --git a/skins/base/views/molecules/MemberTile.js b/skins/base/views/molecules/MemberTile.js index 60d1cadd84..9583c3c4d3 100644 --- a/skins/base/views/molecules/MemberTile.js +++ b/skins/base/views/molecules/MemberTile.js @@ -18,15 +18,70 @@ limitations under the License. var React = require('react'); +var MatrixClientPeg = require("../../../../src/MatrixClientPeg"); +var ComponentBroker = require('../../../../src/ComponentBroker'); var MemberTileController = require("../../../../src/controllers/molecules/MemberTile"); +var MemberInfo = ComponentBroker.get('molecules/MemberInfo'); module.exports = React.createClass({ displayName: 'MemberTile', mixins: [MemberTileController], + + // XXX: should these be in the controller? + getInitialState: function() { + return { 'hover': false }; + }, + + mouseEnter: function(e) { + this.setState({ 'hover': true }); + }, + + mouseLeave: function(e) { + this.setState({ 'hover': false }); + }, + render: function() { + var power; + if (this.props.member) { + var img = "img/p/p" + Math.floor(20 * this.props.member.powerLevelNorm / 100) + ".png"; + power = ; + } + var presenceClass = "mx_MemberTile_offline"; + var mainClassName = "mx_MemberTile "; + if (this.props.member.user) { + if (this.props.member.user.presence === "online") { + presenceClass = "mx_MemberTile_online"; + } + else if (this.props.member.user.presence === "unavailable") { + presenceClass = "mx_MemberTile_unavailable"; + } + } + mainClassName += presenceClass; + + var name; + if (this.state.hover) { + name = +
+ + {this.props.member.name} +
+ } + else { + name = +
+ {this.props.member.name} +
+ } + return ( -
-
{this.props.member.name}
+
+
+ + { power } +
+ { name }
); } diff --git a/skins/base/views/molecules/MessageComposer.js b/skins/base/views/molecules/MessageComposer.js index 89c426cb2b..639c5bff0f 100644 --- a/skins/base/views/molecules/MessageComposer.js +++ b/skins/base/views/molecules/MessageComposer.js @@ -18,16 +18,46 @@ limitations under the License. var React = require('react'); +var MatrixClientPeg = require("../../../../src/MatrixClientPeg"); var MessageComposerController = require("../../../../src/controllers/molecules/MessageComposer"); +var ContentMessages = require("../../../../src/ContentMessages"); module.exports = React.createClass({ displayName: 'MessageComposer', mixins: [MessageComposerController], + onUploadClick: function(ev) { + this.refs.uploadInput.getDOMNode().click(); + }, + + onUploadFileSelected: function(ev) { + var files = ev.target.files; + // MessageComposer shouldn't have to rely on it's parent passing in a callback to upload a file + if (files && files.length > 0) { + this.props.uploadFile(files[0]); + } + this.refs.uploadInput.getDOMNode().value = null; + }, + render: function() { + var me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId); + var uploadInputStyle = {display: 'none'}; return (
-
+ save_button = ( +
+ Save +
+ ); + } else { + name = ; + if (topic) topic_el =
{ topic.getContent().topic }
; + settings_button = ( +
+ +
+ ); + } + + header = +
+
+
+ +
+
+
+ { name } +
+ { topic_el } +
+
+ {callButtons} +
+ { save_button } + { settings_button } +
+ +
+
+ +
+
+ +
+
+
+ } + return (
- {this.props.room.name} + { header }
); }, }); - diff --git a/skins/base/views/molecules/RoomSettings.js b/skins/base/views/molecules/RoomSettings.js new file mode 100644 index 0000000000..36c1f4c29e --- /dev/null +++ b/skins/base/views/molecules/RoomSettings.js @@ -0,0 +1,213 @@ +/* +Copyright 2015 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. +*/ + +'use strict'; + +var React = require('react'); +var MatrixClientPeg = require("../../../../src/MatrixClientPeg"); + +var RoomSettingsController = require("../../../../src/controllers/molecules/RoomSettings"); + +module.exports = React.createClass({ + displayName: 'RoomSettings', + mixins: [RoomSettingsController], + + getTopic: function() { + return this.refs.topic.getDOMNode().value; + }, + + getJoinRules: function() { + return this.refs.is_private.getDOMNode().checked ? "invite" : "public"; + }, + + getHistoryVisibility: function() { + return this.refs.share_history.getDOMNode().checked ? "shared" : "invited"; + }, + + getPowerLevels: function() { + if (!this.state.power_levels_changed) return undefined; + + var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', ''); + power_levels = power_levels.getContent(); + + var new_power_levels = { + ban: parseInt(this.refs.ban.getDOMNode().value), + kick: parseInt(this.refs.kick.getDOMNode().value), + redact: parseInt(this.refs.redact.getDOMNode().value), + invite: parseInt(this.refs.invite.getDOMNode().value), + events_default: parseInt(this.refs.events_default.getDOMNode().value), + state_default: parseInt(this.refs.state_default.getDOMNode().value), + users_default: parseInt(this.refs.users_default.getDOMNode().value), + users: power_levels.users, + events: power_levels.events, + }; + + return new_power_levels; + }, + + onPowerLevelsChanged: function() { + this.setState({ + power_levels_changed: true + }); + }, + + render: function() { + var topic = this.props.room.currentState.getStateEvents('m.room.topic', ''); + if (topic) topic = topic.getContent().topic; + + var join_rule = this.props.room.currentState.getStateEvents('m.room.join_rules', ''); + if (join_rule) join_rule = join_rule.getContent().join_rule; + + var history_visibility = this.props.room.currentState.getStateEvents('m.room.history_visibility', ''); + if (history_visibility) history_visibility = history_visibility.getContent().history_visibility; + + var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', ''); + + if (power_levels) { + power_levels = power_levels.getContent(); + + var ban_level = parseInt(power_levels.ban); + var kick_level = parseInt(power_levels.kick); + var redact_level = parseInt(power_levels.redact); + var invite_level = parseInt(power_levels.invite || 0); + var send_level = parseInt(power_levels.events_default || 0); + var state_level = parseInt(power_levels.state_default || 0); + var default_user_level = parseInt(power_levels.users_default || 0); + + if (power_levels.ban == undefined) ban_level = 50; + if (power_levels.kick == undefined) kick_level = 50; + if (power_levels.redact == undefined) redact_level = 50; + + var user_levels = power_levels.users || []; + var events_levels = power_levels.events || []; + + var user_id = MatrixClientPeg.get().credentials.userId; + + var current_user_level = user_levels[user_id]; + if (current_user_level == undefined) current_user_level = default_user_level; + + var power_level_level = events_levels["m.room.power_levels"]; + if (power_level_level == undefined) { + power_level_level = state_level; + } + + var can_change_levels = current_user_level >= power_level_level; + } else { + var ban_level = 50; + var kick_level = 50; + var redact_level = 50; + var invite_level = 0; + var send_level = 0; + var state_level = 0; + var default_user_level = 0; + + var user_levels = []; + var events_levels = []; + + var current_user_level = 0; + + var power_level_level = 0; + + var can_change_levels = false; + } + + var banned = this.props.room.getMembersWithMemership("ban"); + + return ( +
+