Compare commits

...

9 Commits

Author SHA1 Message Date
Ajay Bura
1487dcbadc Fix login with CAS #165
Signed-off-by: Ajay Bura <ajbura@gmail.com>
2021-11-14 13:35:01 +05:30
Krishan
a4b27fdeab Fixed pull request preview deploys (#166)
* Update and rename pull-request.yml to build-pull-request.yml

* Create deploy-pull-request.yml
2021-11-14 12:54:17 +05:30
Ajay Bura
1137c11c59 Bug fixed
Signed-off-by: Ajay Bura <ajbura@gmail.com>
2021-11-14 11:31:22 +05:30
Samuel Dionne-Riel
14cd84dab7 Add basic support for displaying emotes (#161) 2021-11-14 10:32:32 +05:30
Ajay Bura
b5c5cd9586 Fix add initial_device_display_name on register
Signed-off-by: Ajay Bura <ajbura@gmail.com>
2021-11-11 16:56:36 +05:30
Ajay Bura
85cc4cb8f7 Fix cropped loading and login screen
Signed-off-by: Ajay Bura <ajbura@gmail.com>
2021-11-11 16:47:08 +05:30
Ajay Bura
cf6732fb29 Fix crash on profile opening
Signed-off-by: Ajay Bura <ajbura@gmail.com>
2021-11-11 16:45:55 +05:30
Ajay Bura
1207f5abad Fixed error on register, zoom on safari and removed webpack copying env vars to bundle
Signed-off-by: Ajay Bura <ajbura@gmail.com>
2021-11-11 14:09:06 +05:30
Samuel Dionne-Riel
6e9394ec7a Use Unicode aware character-wise slicing (#159) 2021-11-10 13:30:25 +05:30
28 changed files with 199 additions and 93 deletions

View File

@@ -0,0 +1,32 @@
name: 'Build PR'
on:
pull_request:
types: ['opened', 'synchronize']
jobs:
build:
runs-on: ubuntu-latest
env:
PR_NUMBER: ${{github.event.number}}
steps:
- uses: actions/checkout@v2
- name: Build
run: npm install && npm run build
- name: Upload Artifact
uses: actions/upload-artifact@v2
with:
name: previewbuild
path: dist
retention-days: 1
- uses: actions/github-script@v3.1.0
with:
script: |
var fs = require('fs');
fs.writeFileSync('${{github.workspace}}/pr.json', JSON.stringify(context.payload.pull_request));
- name: Upload PR Info
uses: actions/upload-artifact@v2
with:
name: pr.json
path: pr.json
retention-days: 1

View File

@@ -0,0 +1,78 @@
name: Upload Preview Build to Netlify
on:
workflow_run:
workflows: ["Build PR"]
types:
- completed
jobs:
build:
runs-on: ubuntu-latest
if: >
${{ github.event.workflow_run.conclusion == 'success' }}
steps:
# There's a 'download artifact' action but it hasn't been updated for the
# workflow_run action (https://github.com/actions/download-artifact/issues/60)
# so instead we get this mess:
- name: 'Download artifact'
uses: actions/github-script@v3.1.0
with:
script: |
var artifacts = await github.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{github.event.workflow_run.id }},
});
var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "previewbuild"
})[0];
var download = await github.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
var fs = require('fs');
fs.writeFileSync('${{github.workspace}}/previewbuild.zip', Buffer.from(download.data));
var prInfoArtifact = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "pr.json"
})[0];
var download = await github.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: prInfoArtifact.id,
archive_format: 'zip',
});
var fs = require('fs');
fs.writeFileSync('${{github.workspace}}/pr.json.zip', Buffer.from(download.data));
- name: Extract Artifacts
run: unzip -d dist previewbuild.zip && rm previewbuild.zip && unzip pr.json.zip && rm pr.json.zip
- name: 'Read PR Info'
id: readctx
uses: actions/github-script@v3.1.0
with:
script: |
var fs = require('fs');
var pr = JSON.parse(fs.readFileSync('${{github.workspace}}/pr.json'));
console.log(`::set-output name=prnumber::${pr.number}`);
- name: Deploy to Netlify
id: netlify
uses: nwtgck/actions-netlify@v1.2
with:
publish-dir: dist
deploy-message: "Deploy from GitHub Actions"
# These don't work because we're in workflow_run
enable-pull-request-comment: false
enable-commit-comment: false
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE3_ID }}
timeout-minutes: 1
- name: Edit PR Description
uses: velas/pr-description@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
pull-request-number: ${{ steps.readctx.outputs.prnumber }}
description-message: |
Preview: ${{ steps.netlify.outputs.deploy-url }}
⚠️ Do you trust the author of this PR? Maybe this build will steal your keys or give you malware. Exercise caution. Use test accounts.

View File

@@ -1,30 +0,0 @@
name: 'Netlify Preview Deploy'
on:
pull_request_target:
types: ['opened', 'synchronize']
jobs:
deploy:
name: "Deploy to Netlify"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: jsmrcaga/action-netlify-deploy@master
with:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE3_ID }}
BUILD_DIRECTORY: "dist"
- name: Post on PR
uses: nwtgck/actions-netlify@v1.1
with:
publish-dir: "dist"
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-message: "Deploy from GitHub Actions"
enable-pull-request-comment: true
enable-commit-comment: false
overwrites-pull-request-comment: true
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE3_ID }}

View File

@@ -57,7 +57,7 @@ To set default Homeserver on login and register page, place a customized [`confi
## License ## License
Copyright (c) 2021 Ajay Bura (ajbura) and other contributors Copyright (c) 2021 Ajay Bura (ajbura) and contributors
Code licensed under the MIT License: <http://opensource.org/licenses/MIT> Code licensed under the MIT License: <http://opensource.org/licenses/MIT>

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "cinny", "name": "cinny",
"version": "1.5.0", "version": "1.5.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cinny", "name": "cinny",
"version": "1.5.0", "version": "1.5.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.4.tgz", "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.4.tgz",

View File

@@ -1,6 +1,6 @@
{ {
"name": "cinny", "name": "cinny",
"version": "1.5.0", "version": "1.5.1",
"description": "Yet another matrix client", "description": "Yet another matrix client",
"main": "index.js", "main": "index.js",
"engines": { "engines": {

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0 maximum-scale=1.0 user-scalable=no">
<link href="https://api.fontshare.com/css?f[]=supreme@300,301,400,401,500,501,700,701&display=swap" rel="stylesheet"> <link href="https://api.fontshare.com/css?f[]=supreme@300,301,400,401,500,501,700,701&display=swap" rel="stylesheet">
<title>Cinny</title> <title>Cinny</title>
<meta name="name" content="Cinny"> <meta name="name" content="Cinny">

View File

@@ -29,7 +29,7 @@ function Avatar({
{ {
iconSrc !== null iconSrc !== null
? <RawIcon size={size} src={iconSrc} /> ? <RawIcon size={size} src={iconSrc} />
: text !== null && <Text variant={textSize}>{text}</Text> : text !== null && <Text variant={textSize}>{[...text][0]}</Text>
} }
</span> </span>
) )

View File

@@ -48,7 +48,7 @@ function ImageUpload({
> >
<Avatar <Avatar
imageSrc={imageSrc} imageSrc={imageSrc}
text={text.slice(0, 1)} text={text}
bgColor={bgColor} bgColor={bgColor}
size="large" size="large"
/> />

View File

@@ -106,10 +106,17 @@ MessageReply.propTypes = {
content: PropTypes.string.isRequired, content: PropTypes.string.isRequired,
}; };
function MessageContent({ content, isMarkdown, isEdited }) { function MessageContent({
senderName,
content,
isMarkdown,
isEdited,
msgType,
}) {
return ( return (
<div className="message__content"> <div className="message__content">
<div className="text text-b1"> <div className="text text-b1">
{ msgType === 'm.emote' && `* ${senderName} ` }
{ isMarkdown ? genMarkdown(content) : linkifyContent(content) } { isMarkdown ? genMarkdown(content) : linkifyContent(content) }
</div> </div>
{ isEdited && <Text className="message__content-edited" variant="b3">(edited)</Text>} { isEdited && <Text className="message__content-edited" variant="b3">(edited)</Text>}
@@ -121,9 +128,11 @@ MessageContent.defaultProps = {
isEdited: false, isEdited: false,
}; };
MessageContent.propTypes = { MessageContent.propTypes = {
senderName: PropTypes.string.isRequired,
content: PropTypes.node.isRequired, content: PropTypes.node.isRequired,
isMarkdown: PropTypes.bool, isMarkdown: PropTypes.bool,
isEdited: PropTypes.bool, isEdited: PropTypes.bool,
msgType: PropTypes.string.isRequired,
}; };
function MessageEdit({ content, onSave, onCancel }) { function MessageEdit({ content, onSave, onCancel }) {
@@ -228,10 +237,27 @@ MessageOptions.propTypes = {
function Message({ function Message({
avatar, header, reply, content, editContent, reactions, options, avatar, header, reply, content, editContent, reactions, options,
msgType,
}) { }) {
const msgClass = header === null ? ' message--content-only' : ' message--full'; const className = [
'message',
header === null ? ' message--content-only' : ' message--full',
];
switch (msgType) {
case 'm.text':
className.push('message--type-text');
break;
case 'm.emote':
className.push('message--type-emote');
break;
case 'm.notice':
className.push('message--type-notice');
break;
default:
}
return ( return (
<div className={`message${msgClass}`}> <div className={className.join(' ')}>
<div className="message__avatar-container"> <div className="message__avatar-container">
{avatar !== null && avatar} {avatar !== null && avatar}
</div> </div>
@@ -254,6 +280,7 @@ Message.defaultProps = {
editContent: null, editContent: null,
reactions: null, reactions: null,
options: null, options: null,
msgType: 'm.text',
}; };
Message.propTypes = { Message.propTypes = {
avatar: PropTypes.node, avatar: PropTypes.node,
@@ -263,6 +290,7 @@ Message.propTypes = {
editContent: PropTypes.node, editContent: PropTypes.node,
reactions: PropTypes.node, reactions: PropTypes.node,
options: PropTypes.node, options: PropTypes.node,
msgType: PropTypes.string,
}; };
export { export {

View File

@@ -410,3 +410,14 @@
} }
} }
} }
.message.message--type-emote {
.message__content {
font-style: italic;
// Remove blockness of first `<p>` so that markdown emotes stay on one line.
p:first-of-type {
display: inline;
}
}
}

View File

@@ -18,7 +18,7 @@ function PeopleSelector({
onClick={onClick} onClick={onClick}
type="button" type="button"
> >
<Avatar imageSrc={avatarSrc} text={name.slice(0, 1)} bgColor={color} size="extra-small" /> <Avatar imageSrc={avatarSrc} text={name} bgColor={color} size="extra-small" />
<Text className="people-selector__name" variant="b1">{name}</Text> <Text className="people-selector__name" variant="b1">{name}</Text>
{peopleRole !== null && <Text className="people-selector__role" variant="b3">{peopleRole}</Text>} {peopleRole !== null && <Text className="people-selector__role" variant="b3">{peopleRole}</Text>}
</button> </button>

View File

@@ -17,7 +17,7 @@ function RoomIntro({
}) { }) {
return ( return (
<div className="room-intro"> <div className="room-intro">
<Avatar imageSrc={avatarSrc} text={name.slice(0, 1)} bgColor={colorMXID(roomId)} size="large" /> <Avatar imageSrc={avatarSrc} text={name} bgColor={colorMXID(roomId)} size="large" />
<div className="room-intro__content"> <div className="room-intro__content">
<Text className="room-intro__name" variant="h1">{heading}</Text> <Text className="room-intro__name" variant="h1">{heading}</Text>
<Text className="room-intro__desc" variant="b1">{linkifyContent(desc)}</Text> <Text className="room-intro__desc" variant="b1">{linkifyContent(desc)}</Text>

View File

@@ -51,7 +51,7 @@ function RoomSelector({
content={( content={(
<> <>
<Avatar <Avatar
text={name.slice(0, 1)} text={name}
bgColor={colorMXID(roomId)} bgColor={colorMXID(roomId)}
imageSrc={imageSrc} imageSrc={imageSrc}
iconSrc={iconSrc} iconSrc={iconSrc}

View File

@@ -22,7 +22,7 @@ function RoomTile({
<Avatar <Avatar
imageSrc={avatarSrc} imageSrc={avatarSrc}
bgColor={colorMXID(id)} bgColor={colorMXID(id)}
text={name.slice(0, 1)} text={name}
/> />
</div> </div>
<div className="room-tile__content"> <div className="room-tile__content">

View File

@@ -70,7 +70,7 @@ function ProfileAvatarMenu() {
tooltip={profile.displayName} tooltip={profile.displayName}
imageSrc={profile.avatarUrl !== null ? mx.mxcUrlToHttp(profile.avatarUrl, 42, 42, 'crop') : null} imageSrc={profile.avatarUrl !== null ? mx.mxcUrlToHttp(profile.avatarUrl, 42, 42, 'crop') : null}
bgColor={colorMXID(mx.getUserId())} bgColor={colorMXID(mx.getUserId())}
text={profile.displayName.slice(0, 1)} text={profile.displayName}
/> />
)} )}
/> />
@@ -190,7 +190,7 @@ function SideBar() {
tooltip={room.name} tooltip={room.name}
bgColor={colorMXID(room.roomId)} bgColor={colorMXID(room.roomId)}
imageSrc={room.getAvatarUrl(initMatrix.matrixClient.baseUrl, 42, 42, 'crop') || null} imageSrc={room.getAvatarUrl(initMatrix.matrixClient.baseUrl, 42, 42, 'crop') || null}
text={room.name.slice(0, 1)} text={room.name}
isUnread={notifications.hasNoti(sRoomId)} isUnread={notifications.hasNoti(sRoomId)}
notificationCount={abbreviateNumber(notifications.getTotalNoti(sRoomId))} notificationCount={abbreviateNumber(notifications.getTotalNoti(sRoomId))}
isAlert={notifications.getHighlightNoti(sRoomId) !== 0} isAlert={notifications.getHighlightNoti(sRoomId) !== 0}

View File

@@ -249,15 +249,15 @@ function ProfileViewer() {
}, [isOpen]); }, [isOpen]);
function renderProfile() { function renderProfile() {
const member = room.getMember(userId) || mx.getUser(userId); const member = room.getMember(userId) || mx.getUser(userId) || {};
const avatarMxc = member.getMxcAvatarUrl() || member.avatarUrl; const avatarMxc = member.getMxcAvatarUrl?.() || member.avatarUrl;
return ( return (
<div className="profile-viewer"> <div className="profile-viewer">
<div className="profile-viewer__user"> <div className="profile-viewer__user">
<Avatar <Avatar
imageSrc={!avatarMxc ? null : mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop')} imageSrc={!avatarMxc ? null : mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop')}
text={username.slice(0, 1)} text={username}
bgColor={colorMXID(userId)} bgColor={colorMXID(userId)}
size="large" size="large"
/> />

View File

@@ -8,7 +8,7 @@ import dateFormat from 'dateformat';
import initMatrix from '../../../client/initMatrix'; import initMatrix from '../../../client/initMatrix';
import cons from '../../../client/state/cons'; import cons from '../../../client/state/cons';
import { redactEvent, sendReaction } from '../../../client/action/roomTimeline'; import { redactEvent, sendReaction } from '../../../client/action/roomTimeline';
import { getUsername, getUsernameOfRoomMember, doesRoomHaveUnread } from '../../../util/matrixUtil'; import { getUsername, getUsernameOfRoomMember } from '../../../util/matrixUtil';
import colorMXID from '../../../util/colorMXID'; import colorMXID from '../../../util/colorMXID';
import { diffMinutes, isNotInSameDay, getEventCords } from '../../../util/common'; import { diffMinutes, isNotInSameDay, getEventCords } from '../../../util/common';
import { openEmojiBoard, openProfileViewer, openReadReceipts } from '../../../client/action/navigation'; import { openEmojiBoard, openProfileViewer, openReadReceipts } from '../../../client/action/navigation';
@@ -191,6 +191,7 @@ function RoomViewContent({
const [onPagination, setOnPagination] = useState(null); const [onPagination, setOnPagination] = useState(null);
const [editEvent, setEditEvent] = useState(null); const [editEvent, setEditEvent] = useState(null);
const mx = initMatrix.matrixClient; const mx = initMatrix.matrixClient;
const noti = initMatrix.notifications;
function autoLoadTimeline() { function autoLoadTimeline() {
if (timelineScroll.isScrollable() === true) return; if (timelineScroll.isScrollable() === true) return;
@@ -199,7 +200,7 @@ function RoomViewContent({
function trySendingReadReceipt() { function trySendingReadReceipt() {
const { room, timeline } = roomTimeline; const { room, timeline } = roomTimeline;
if ( if (
(doesRoomHaveUnread(room) || initMatrix.notifications.hasNoti(roomId)) (noti.doesRoomHaveUnread(room) || noti.hasNoti(roomId))
&& timeline.length !== 0) { && timeline.length !== 0) {
mx.sendReadReceipt(timeline[timeline.length - 1]); mx.sendReadReceipt(timeline[timeline.length - 1]);
} }
@@ -282,6 +283,7 @@ function RoomViewContent({
let content = mEvent.getContent().body; let content = mEvent.getContent().body;
if (typeof content === 'undefined') return null; if (typeof content === 'undefined') return null;
const msgType = mEvent.getContent()?.msgtype;
let reply = null; let reply = null;
let reactions = null; let reactions = null;
let isMarkdown = mEvent.getContent().format === 'org.matrix.custom.html'; let isMarkdown = mEvent.getContent().format === 'org.matrix.custom.html';
@@ -356,7 +358,7 @@ function RoomViewContent({
<button type="button" onClick={() => openProfileViewer(mEvent.sender.userId, roomId)}> <button type="button" onClick={() => openProfileViewer(mEvent.sender.userId, roomId)}>
<Avatar <Avatar
imageSrc={mEvent.sender.getAvatarUrl(initMatrix.matrixClient.baseUrl, 36, 36, 'crop')} imageSrc={mEvent.sender.getAvatarUrl(initMatrix.matrixClient.baseUrl, 36, 36, 'crop')}
text={getUsernameOfRoomMember(mEvent.sender).slice(0, 1)} text={getUsernameOfRoomMember(mEvent.sender)}
bgColor={senderMXIDColor} bgColor={senderMXIDColor}
size="small" size="small"
/> />
@@ -379,8 +381,10 @@ function RoomViewContent({
); );
const userContent = ( const userContent = (
<MessageContent <MessageContent
senderName={getUsernameOfRoomMember(mEvent.sender)}
isMarkdown={isMarkdown} isMarkdown={isMarkdown}
content={isMedia(mEvent) ? genMediaContent(mEvent) : content} content={isMedia(mEvent) ? genMediaContent(mEvent) : content}
msgType={msgType}
isEdited={isEdited} isEdited={isEdited}
/> />
); );
@@ -496,6 +500,7 @@ function RoomViewContent({
header={userHeader} header={userHeader}
reply={userReply} reply={userReply}
content={editEvent !== null && isEditingEvent ? null : userContent} content={editEvent !== null && isEditingEvent ? null : userContent}
msgType={msgType}
editContent={editEvent !== null && isEditingEvent ? ( editContent={editEvent !== null && isEditingEvent ? (
<MessageEdit <MessageEdit
content={content} content={content}

View File

@@ -24,7 +24,7 @@ function RoomViewHeader({ roomId }) {
return ( return (
<Header> <Header>
<Avatar imageSrc={avatarSrc} text={roomName.slice(0, 1)} bgColor={colorMXID(roomId)} size="small" /> <Avatar imageSrc={avatarSrc} text={roomName} bgColor={colorMXID(roomId)} size="small" />
<TitleWrapper> <TitleWrapper>
<Text variant="h2">{roomName}</Text> <Text variant="h2">{roomName}</Text>
{ typeof roomTopic !== 'undefined' && <p title={roomTopic} className="text text-b3">{roomTopic}</p>} { typeof roomTopic !== 'undefined' && <p title={roomTopic} className="text text-b3">{roomTopic}</p>}

View File

@@ -156,7 +156,7 @@ function Login({ loginFlow, baseUrl }) {
const [typeIndex, setTypeIndex] = useState(0); const [typeIndex, setTypeIndex] = useState(0);
const loginTypes = ['Username', 'Email']; const loginTypes = ['Username', 'Email'];
const isPassword = loginFlow?.filter((flow) => flow.type === 'm.login.password')[0]; const isPassword = loginFlow?.filter((flow) => flow.type === 'm.login.password')[0];
const ssoProviders = loginFlow?.filter((flow) => flow.type.match(/^m.login.(sso|cas)$/))[0]; const ssoProviders = loginFlow?.filter((flow) => flow.type === 'm.login.sso')[0];
const initialValues = { const initialValues = {
username: '', password: '', email: '', other: '', username: '', password: '', email: '', other: '',
@@ -248,7 +248,7 @@ function Login({ loginFlow, baseUrl }) {
{ssoProviders && isPassword && <Text className="sso__divider">OR</Text>} {ssoProviders && isPassword && <Text className="sso__divider">OR</Text>}
{ssoProviders && ( {ssoProviders && (
<SSOButtons <SSOButtons
type={ssoProviders.type.match(/^m.login.(sso|cas)$/)[1]} type="sso"
identityProviders={ssoProviders.identity_providers} identityProviders={ssoProviders.identity_providers}
baseUrl={baseUrl} baseUrl={baseUrl}
/> />
@@ -269,7 +269,7 @@ function Register({ registerInfo, loginFlow, baseUrl }) {
const [process, setProcess] = useState({}); const [process, setProcess] = useState({});
const formRef = useRef(); const formRef = useRef();
const ssoProviders = loginFlow?.filter((flow) => flow.type.match(/^m.login.(sso|cas)$/))[0]; const ssoProviders = loginFlow?.filter((flow) => flow.type === 'm.login.sso')[0];
const isDisabled = registerInfo.errcode !== undefined; const isDisabled = registerInfo.errcode !== undefined;
const { flows, params, session } = registerInfo; const { flows, params, session } = registerInfo;
@@ -332,8 +332,8 @@ function Register({ registerInfo, loginFlow, baseUrl }) {
actions.setSubmitting(false); actions.setSubmitting(false);
}).catch((err) => { }).catch((err) => {
const msg = err.message || err.error; const msg = err.message || err.error;
if (['M_USER_IN_USE', 'M_INVALID_USERNAME', 'M_EXCLUSIVE'].indexOf(err.errcode) > 0) { if (['M_USER_IN_USE', 'M_INVALID_USERNAME', 'M_EXCLUSIVE'].indexOf(err.errcode) > -1) {
actions.setErrors({ username: err.errCode === 'M_USER_IN_USE' ? 'Username is already taken' : msg }); actions.setErrors({ username: err.errcode === 'M_USER_IN_USE' ? 'Username is already taken' : msg });
} else if (msg) actions.setErrors({ other: msg }); } else if (msg) actions.setErrors({ other: msg });
actions.setSubmitting(false); actions.setSubmitting(false);
@@ -452,7 +452,7 @@ function Register({ registerInfo, loginFlow, baseUrl }) {
)} )}
{isDisabled && ssoProviders && ( {isDisabled && ssoProviders && (
<SSOButtons <SSOButtons
type={ssoProviders.type.match(/^m.login.(sso|cas)$/)[1]} type="sso"
identityProviders={ssoProviders.identity_providers} identityProviders={ssoProviders.identity_providers}
baseUrl={baseUrl} baseUrl={baseUrl}
/> />

View File

@@ -1,6 +1,6 @@
.auth__base { .auth__base {
--pattern-size: 48px; --pattern-size: 48px;
min-height: 100vh; min-height: 100%;
background-color: var(--bg-surface-low); background-color: var(--bg-surface-low);
background-image: radial-gradient(rgba(0, 0, 0, 6%) 2px, rgba(0, 0, 0, 0%) 2px); background-image: radial-gradient(rgba(0, 0, 0, 6%) 2px, rgba(0, 0, 0, 0%) 2px);

View File

@@ -18,7 +18,7 @@
top: 0; top: 0;
left: 0; left: 0;
width: 100vw; width: 100vw;
height: 100vh; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@@ -75,7 +75,10 @@ async function completeRegisterStage(
try { try {
const result = await tempClient.registerRequest({ const result = await tempClient.registerRequest({
username, password, auth, username,
password,
auth,
initial_device_display_name: cons.DEVICE_DISPLAY_NAME,
}); });
const data = { completed: result.completed || [] }; const data = { completed: result.completed || [] };
if (result.access_token) { if (result.access_token) {

View File

@@ -31,6 +31,7 @@ class InitMatrix extends EventEmitter {
sessionStore: new sdk.WebStorageSessionStore(global.localStorage), sessionStore: new sdk.WebStorageSessionStore(global.localStorage),
cryptoStore: new sdk.IndexedDBCryptoStore(global.indexedDB, 'crypto-store'), cryptoStore: new sdk.IndexedDBCryptoStore(global.indexedDB, 'crypto-store'),
deviceId: secret.deviceId, deviceId: secret.deviceId,
timelineSupport: true,
}); });
await this.matrixClient.initCrypto(); await this.matrixClient.initCrypto();

View File

@@ -1,5 +1,5 @@
const cons = { const cons = {
version: '1.5.0', version: '1.5.1',
secretKey: { secretKey: {
ACCESS_TOKEN: 'cinny_access_token', ACCESS_TOKEN: 'cinny_access_token',
DEVICE_ID: 'cinny_device_id', DEVICE_ID: 'cinny_device_id',

View File

@@ -290,7 +290,13 @@ button {
overflow: visible; overflow: visible;
-webkit-appearance: button; -webkit-appearance: button;
} }
textarea, input[type="text"] { textarea,
input,
input[type],
input[type=text],
input[type=username],
input[type=password],
input[type=email] {
-webkit-appearance: none; -webkit-appearance: none;
-moz-appearance: none; -moz-appearance: none;
appearance: none; appearance: none;

View File

@@ -48,30 +48,6 @@ async function isRoomAliasAvailable(alias) {
} }
} }
function doesRoomHaveUnread(room) {
const userId = initMatrix.matrixClient.getUserId();
const readUpToId = room.getEventReadUpTo(userId);
const supportEvents = ['m.room.message', 'm.room.encrypted', 'm.sticker'];
if (room.timeline.length
&& room.timeline[room.timeline.length - 1].sender
&& room.timeline[room.timeline.length - 1].sender.userId === userId
&& room.timeline[room.timeline.length - 1].getType() !== 'm.room.member') {
return false;
}
for (let i = room.timeline.length - 1; i >= 0; i -= 1) {
const event = room.timeline[i];
if (event.getId() === readUpToId) return false;
if (supportEvents.includes(event.getType())) {
return true;
}
}
return true;
}
function getPowerLabel(powerLevel) { function getPowerLabel(powerLevel) {
if (powerLevel > 9000) return 'Goku'; if (powerLevel > 9000) return 'Goku';
if (powerLevel > 100) return 'Founder'; if (powerLevel > 100) return 'Founder';
@@ -82,5 +58,5 @@ function getPowerLabel(powerLevel) {
export { export {
getBaseUrl, getUsername, getUsernameOfRoomMember, getBaseUrl, getUsername, getUsernameOfRoomMember,
isRoomAliasAvailable, doesRoomHaveUnread, getPowerLabel, isRoomAliasAvailable, getPowerLabel,
}; };

View File

@@ -1,6 +1,5 @@
const HtmlWebpackPlugin = require('html-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin');
const FaviconsWebpackPlugin = require('favicons-webpack-plugin'); const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const webpack = require('webpack');
const CopyPlugin = require("copy-webpack-plugin"); const CopyPlugin = require("copy-webpack-plugin");
module.exports = { module.exports = {
@@ -66,9 +65,6 @@ module.exports = {
} }
} }
}), }),
new webpack.DefinePlugin({
'process.env': JSON.stringify(process.env),
}),
new CopyPlugin({ new CopyPlugin({
patterns: [ patterns: [
{ from: 'olm.wasm' }, { from: 'olm.wasm' },