diff --git a/src/App.tsx b/src/App.tsx index 46e5698cbecda3194fb6b3339a693989bf2dfd2a..164190cd47fed0c329cc604447246aa064a3e4cf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -36,8 +36,12 @@ const App: React.FC = () => { </> ); + // Some hacky uri decoding + location.href = decodeURIComponent(location.href); + const [hash, setHash] = useState(location.hash); + console.log(hash); useEffect(() => (window.onhashchange = () => setHash(location.hash)), []); if (hash) { diff --git a/src/components/Avatar.scss b/src/components/Avatar.scss index 7895a82fa33a2391b12f2c66aa896fc96c7a87b6..794064aa6030e767cca36210e44872493c2b9fbb 100644 --- a/src/components/Avatar.scss +++ b/src/components/Avatar.scss @@ -14,11 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -@import "../color-scheme"; +@import '../color-scheme'; .avatar { border-radius: 100%; border: 1px solid $borders; - height: 50px; - width: 50px; + height: 60px; + width: 60px; +} + +.avatarNoCrop { + border-radius: 0; } diff --git a/src/components/ClientTile.scss b/src/components/ClientTile.scss index 2beb41aaca5c065067586d80dd4b15dc9f083712..996c56f672ec87db12321c88d3cbac3f6334b40f 100644 --- a/src/components/ClientTile.scss +++ b/src/components/ClientTile.scss @@ -45,12 +45,14 @@ limitations under the License. } p { - margin-right: 20px; + margin-right: 8px; text-align: left; } .button { - width: 50%; + height: 40px; + width: 130px; + margin-top: 16px; } } diff --git a/src/components/HomeserverOptions.tsx b/src/components/HomeserverOptions.tsx index 23a5a6ede5140c366af4d7bf9874fc4b0bd8547a..ab30a3c724d37c7c44e239da3c7872785786dceb 100644 --- a/src/components/HomeserverOptions.tsx +++ b/src/components/HomeserverOptions.tsx @@ -41,7 +41,8 @@ function validateURL(values: FormValues): Partial<FormValues> { try { string().url().parse(values.HSUrl); } catch { - errors.HSUrl = 'This must be a valid url'; + errors.HSUrl = + 'This must be a valid homeserver URL, starting with https://'; } return errors; } @@ -74,7 +75,7 @@ const HomeserverOptions: React.FC<IProps> = ({ link }: IProps) => { muted={!values.HSUrl} type="text" name="HSUrl" - placeholder="https://example.com" + placeholder="Preferred homeserver URL" /> {values.HSUrl && !errors.HSUrl ? ( <Button secondary type="submit"> @@ -92,12 +93,9 @@ const HomeserverOptions: React.FC<IProps> = ({ link }: IProps) => { <div> <h3>About {link.identifier}</h3> <p> - Select a homeserver to learn more about{' '} - {link.identifier}. <br /> - The homeserver will provide metadata about the link such - as an avatar or description. Homeservers will be able to - relate your IP to resources you've opened invites for in - matrix.to. + A homeserver will show you metadata about the link, like + a description. Homeservers will be able to relate your + IP to things you've opened invites for in matrix.to. </p> </div> <img diff --git a/src/components/Input.tsx b/src/components/Input.tsx index b094061e8c0b4592cb4add27d4c37f3c1ff31c79..21ce3424b0d140bc2898aee73f9f483ced2fedb4 100644 --- a/src/components/Input.tsx +++ b/src/components/Input.tsx @@ -29,13 +29,13 @@ interface IProps extends React.InputHTMLAttributes<HTMLElement> { const Input: React.FC<IProps> = ({ className, muted, ...props }) => { const [field, meta] = useField(props); - const error = - meta.touched && meta.error ? ( - <div className="inputError">{meta.error}</div> - ) : null; + const errorBool = meta.touched && meta.value !== '' && meta.error; + const error = errorBool ? ( + <div className="inputError">{meta.error}</div> + ) : null; const classNames = classnames('input', className, { - error: meta.error, + error: errorBool, inputMuted: !!muted, }); diff --git a/src/components/InviteTile.scss b/src/components/InviteTile.scss index 6d236322fbc39cd336e78a48e1b7df6260c01020..f9a8cdd854e035282c63f2c91436bf4030f4b3c9 100644 --- a/src/components/InviteTile.scss +++ b/src/components/InviteTile.scss @@ -14,16 +14,22 @@ See the License for the specific language governing permissions and limitations under the License. */ +@import '../color-scheme'; + .inviteTile { display: grid; row-gap: 24px; .inviteTileClientSelection { - margin: 0 5%; + margin: 0 auto; display: grid; justify-content: space-between; row-gap: 20px; + + h2 + p { + color: $foreground; + } } hr { diff --git a/src/components/InviteTile.tsx b/src/components/InviteTile.tsx index fad18a4ba30cc169918eb6a80d49f76919584c42..269e47edeac1427601fa78e1792f49b5e2137060 100644 --- a/src/components/InviteTile.tsx +++ b/src/components/InviteTile.tsx @@ -87,8 +87,8 @@ const InviteTile: React.FC<IProps> = ({ children, client, link }: IProps) => { advanced = ( <> <hr /> - <h3>Almost done!</h3> - <p>Pick a client to open {link.identifier}</p> + <h2>Almost done!</h2> + <p>Great, pick a client below to confirm and continue</p> <ClientSelection link={link} /> </> ); diff --git a/src/components/RoomPreview.scss b/src/components/RoomPreview.scss index ef82fb94f3f093c5ed83e6004972d7b88c8e9d48..b7e7b367214d445ea1e8fa27d9c82b5201bd1cd6 100644 --- a/src/components/RoomPreview.scss +++ b/src/components/RoomPreview.scss @@ -16,16 +16,15 @@ limitations under the License. .roomPreview { > .avatar { - margin-top: 20px; - margin-bottom: 16px; + margin-bottom: 8px; } > h1 { - font-size: 20px; + font-size: 24px; margin-bottom: 4px; } } .roomTopic { - padding-top: 32px; + padding-top: 8px; } diff --git a/src/components/RoomPreview.tsx b/src/components/RoomPreview.tsx index e7e54044e0b2208332e858a30a98bc9caccb7b99..2874f2b7c6d6b3804a441fd8b959d8ac9ab58ab7 100644 --- a/src/components/RoomPreview.tsx +++ b/src/components/RoomPreview.tsx @@ -31,11 +31,15 @@ const RoomPreview: React.FC<IProps> = ({ room }: IProps) => { : room.aliases ? room.aliases[0] : room.room_id; + const members = + room.num_joined_members > 0 ? ( + <p>{room.num_joined_members.toLocaleString()} members</p> + ) : null; return ( <div className="roomPreview"> <RoomAvatar room={room} /> <h1>{room.name ? room.name : roomAlias}</h1> - <p>{room.num_joined_members.toLocaleString()} members</p> + {members} <p>{roomAlias}</p> </div> ); diff --git a/src/components/TextButton.scss b/src/components/TextButton.scss index a5168e04a5f7ae29215f0a75dbdc34c56ada7b9e..cdaed546aa8eeae897a7302c344dd923b9b13ea2 100644 --- a/src/components/TextButton.scss +++ b/src/components/TextButton.scss @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -@import "../color-scheme"; +@import '../color-scheme'; .textButton { background: none; @@ -24,4 +24,8 @@ limitations under the License. font-weight: normal; font-size: 14px; line-height: 24px; + + &:hover { + cursor: pointer; + } } diff --git a/src/components/Toggle.scss b/src/components/Toggle.scss index e4601b285aae18d162e498ac8152a006561dbbb3..5d8222303c4d27363f4b58d5a1a876d2b54ec681 100644 --- a/src/components/Toggle.scss +++ b/src/components/Toggle.scss @@ -37,4 +37,8 @@ limitations under the License. } } } + + &:hover { + cursor: pointer; + } } diff --git a/src/components/UserPreview.scss b/src/components/UserPreview.scss index 3ff72b6ff392ad426bbde0271993c3308a012730..c711e5a4f793955dee48a47566cf19c29dbfc60d 100644 --- a/src/components/UserPreview.scss +++ b/src/components/UserPreview.scss @@ -20,12 +20,11 @@ limitations under the License. width: 100%; > .avatar { - margin-top: 20px; - margin-bottom: 16px; + margin-bottom: 8px; } h1 { - font-size: 20px; + font-size: 24px; margin-bottom: 4px; } diff --git a/src/components/UserPreview.tsx b/src/components/UserPreview.tsx index 6f90e19e8761d986b95bcc33f7a59a0c2f3aaf6b..b1a38ee07fd9d3cfd45cb056ef439d2e90a745e8 100644 --- a/src/components/UserPreview.tsx +++ b/src/components/UserPreview.tsx @@ -53,7 +53,11 @@ export const InviterPreview: React.FC<InviterPreviewProps> = ({ const avatar = user ? ( <UserAvatar user={user} userId={userId} /> ) : ( - <Avatar label={`Placeholder icon for ${userId}`} avatarUrl={icon} /> + <Avatar + className="avatarNoCrop" + label={`Placeholder icon for ${userId}`} + avatarUrl={icon} + /> ); const className = classNames('miniUserPreview', { centeredMiniUserPreview: !user, diff --git a/src/pages/LinkRouter.tsx b/src/pages/LinkRouter.tsx index ae797aa2392b75267cf2ebca108bba1bc3d7452a..cf3b4d674aa47ae3d8ea4615b64af142a32e231e 100644 --- a/src/pages/LinkRouter.tsx +++ b/src/pages/LinkRouter.tsx @@ -22,6 +22,8 @@ import InvitingClientTile from '../components/InvitingClientTile'; import { parseHash } from '../parser/parser'; import { LinkKind } from '../parser/types'; +/* eslint-disable no-restricted-globals */ + interface IProps { link: string; } @@ -36,8 +38,14 @@ const LinkRouter: React.FC<IProps> = ({ link }: IProps) => { case LinkKind.ParseFailed: feedback = ( <Tile> - <h1>Invalid matrix.to link</h1> - <p>{link}</p> + <p> + That URL doesn't seem right. Links should be in the + format: + </p> + <br /> + <p> + {location.host}/#/{'<'}matrix-resourceidentifier{'>'} + </p> </Tile> ); break;