Merge branch 'main' into jryans/ux-refresh
This commit is contained in:
commit
7a79e68d5e
10 changed files with 196 additions and 5 deletions
|
@ -20,6 +20,9 @@ import {
|
|||
ClientKind,
|
||||
ClientId,
|
||||
Platform,
|
||||
AppleStoreLink,
|
||||
PlayStoreLink,
|
||||
FDroidLink,
|
||||
} from './types';
|
||||
import { LinkKind } from '../parser/types';
|
||||
import logo from '../imgs/element.svg';
|
||||
|
@ -31,7 +34,7 @@ export const Element: LinkedClient = {
|
|||
logo: logo,
|
||||
homepage: 'https://element.io',
|
||||
maturity: Maturity.STABLE,
|
||||
description: 'Fully-featured Matrix client for the Web',
|
||||
description: 'Fully-featured Matrix client',
|
||||
platforms: [Platform.Desktop, Platform.Android, Platform.iOS],
|
||||
experimental: false,
|
||||
clientId: ClientId.Element,
|
||||
|
@ -59,6 +62,11 @@ export const Element: LinkedClient = {
|
|||
}
|
||||
},
|
||||
linkSupport: () => true,
|
||||
installLinks: [
|
||||
new AppleStoreLink('vector', 'id1083446067'),
|
||||
new PlayStoreLink('im.vector.app'),
|
||||
new FDroidLink('im.vector.app'),
|
||||
],
|
||||
};
|
||||
|
||||
export const ElementDevelop: LinkedClient = {
|
||||
|
@ -94,4 +102,5 @@ export const ElementDevelop: LinkedClient = {
|
|||
}
|
||||
},
|
||||
linkSupport: () => true,
|
||||
installLinks: [],
|
||||
};
|
||||
|
|
|
@ -69,6 +69,7 @@ const Fractal: TextClient = {
|
|||
},
|
||||
|
||||
description: 'Fractal is a Matrix Client written in Rust',
|
||||
installLinks: [],
|
||||
};
|
||||
|
||||
export default Fractal;
|
||||
|
|
|
@ -86,6 +86,7 @@ const Nheko: TextClient = {
|
|||
},
|
||||
description:
|
||||
'A native desktop app for Matrix that feels more like a mainstream chat app.',
|
||||
installLinks: [],
|
||||
};
|
||||
|
||||
export default Nheko;
|
||||
|
|
|
@ -86,6 +86,7 @@ const Weechat: TextClient = {
|
|||
},
|
||||
|
||||
description: 'Command-line Matrix interface using Weechat',
|
||||
installLinks: [],
|
||||
};
|
||||
|
||||
export default Weechat;
|
||||
|
|
|
@ -53,6 +53,79 @@ export enum ClientId {
|
|||
Fractal = 'fractal',
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a native distribution channel for a client.
|
||||
* E.g App store for apple, PlayStore or F-Droid for Android
|
||||
*/
|
||||
export interface InstallLink {
|
||||
createInstallURL(deepLink: SafeLink) : string;
|
||||
// in AppleStoreLink, we can set the cookie here for deeplinking
|
||||
// onInstallChosen(deepLink: SafeLink);
|
||||
platform: Platform;
|
||||
channelId: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export class AppleStoreLink implements InstallLink {
|
||||
constructor(private org: string, private appId: string) {}
|
||||
|
||||
createInstallURL(deepLink: SafeLink) : string {
|
||||
return `https://apps.apple.com/app/${encodeURIComponent(this.org)}/${encodeURIComponent(this.appId)}`;
|
||||
}
|
||||
|
||||
get platform() : Platform {
|
||||
return Platform.iOS;
|
||||
}
|
||||
|
||||
get channelId(): string {
|
||||
return "apple-app-store";
|
||||
}
|
||||
|
||||
get description() {
|
||||
return "Download on the App Store";
|
||||
}
|
||||
}
|
||||
|
||||
export class PlayStoreLink implements InstallLink {
|
||||
constructor(private appId: string) {}
|
||||
|
||||
createInstallURL(deepLink: SafeLink) : string {
|
||||
return `https://play.google.com/store/apps/details?id=${encodeURIComponent(this.appId)}&referrer=${encodeURIComponent(deepLink.originalLink)}`;
|
||||
}
|
||||
|
||||
get platform() : Platform {
|
||||
return Platform.Android;
|
||||
}
|
||||
|
||||
get channelId(): string {
|
||||
return "play-store";
|
||||
}
|
||||
|
||||
get description() {
|
||||
return "Get it on Google Play";
|
||||
}
|
||||
}
|
||||
|
||||
export class FDroidLink implements InstallLink {
|
||||
constructor(private appId: string) {}
|
||||
|
||||
createInstallURL(deepLink: SafeLink) : string {
|
||||
return `https://f-droid.org/packages/${encodeURIComponent(this.appId)}`;
|
||||
}
|
||||
|
||||
get platform() : Platform {
|
||||
return Platform.Android;
|
||||
}
|
||||
|
||||
get channelId(): string {
|
||||
return "fdroid";
|
||||
}
|
||||
|
||||
get description() {
|
||||
return "Get it on F-Droid";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The descriptive details of a client
|
||||
*/
|
||||
|
@ -67,6 +140,7 @@ export interface ClientDescription {
|
|||
clientId: ClientId;
|
||||
experimental: boolean;
|
||||
linkSupport: (link: SafeLink) => boolean;
|
||||
installLinks: InstallLink[];
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -51,7 +51,8 @@ limitations under the License.
|
|||
|
||||
.button {
|
||||
height: 40px;
|
||||
width: 130px;
|
||||
min-width: 130px;
|
||||
max-width: 165px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +67,15 @@ limitations under the License.
|
|||
&:hover {
|
||||
background-color: $app-background;
|
||||
}
|
||||
|
||||
.installLink {
|
||||
display: inline-block;
|
||||
height: 40px;
|
||||
margin: 8px 16px 8px 0;
|
||||
img {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.clientTileLink {
|
||||
|
|
|
@ -14,14 +14,19 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { UAContext } from '@quentin-sommer/react-useragent';
|
||||
|
||||
import { Client, ClientKind } from '../clients/types';
|
||||
import { Client, ClientKind, Platform } from '../clients/types';
|
||||
import { SafeLink } from '../parser/types';
|
||||
import Tile from './Tile';
|
||||
import Button from './Button';
|
||||
|
||||
import appStoreBadge from '../imgs/app-store-us-alt.svg';
|
||||
import playStoreBadge from '../imgs/google-play-us.svg';
|
||||
import fdroidBadge from '../imgs/fdroid-badge.png';
|
||||
|
||||
import './ClientTile.scss';
|
||||
|
||||
interface IProps {
|
||||
|
@ -29,17 +34,54 @@ interface IProps {
|
|||
link: SafeLink;
|
||||
}
|
||||
|
||||
interface IInstallBadgeImages {
|
||||
[index: string]: string;
|
||||
}
|
||||
|
||||
const installBadgeImages : IInstallBadgeImages = {
|
||||
"fdroid": fdroidBadge,
|
||||
"apple-app-store": appStoreBadge,
|
||||
"play-store": playStoreBadge
|
||||
};
|
||||
|
||||
const ClientTile: React.FC<IProps> = ({ client, link }: IProps) => {
|
||||
const inviteLine =
|
||||
client.kind === ClientKind.TEXT_CLIENT ? (
|
||||
<p>{client.toInviteString(link)}</p>
|
||||
) : null;
|
||||
|
||||
const { uaResults } = useContext(UAContext);
|
||||
|
||||
const className = classNames('clientTile', {
|
||||
clientTileLink: client.kind === ClientKind.LINKED_CLIENT,
|
||||
});
|
||||
|
||||
let inviteButton: JSX.Element = <></>;
|
||||
const matchingInstallLinks = client.installLinks.filter((installLink) => {
|
||||
if ((uaResults as any).ios) {
|
||||
return installLink.platform === Platform.iOS;
|
||||
} else if ((uaResults as any).android) {
|
||||
return installLink.platform === Platform.Android;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
const hasNativeClient = matchingInstallLinks.length > 0;
|
||||
let installButtons = undefined;
|
||||
if (matchingInstallLinks.length) {
|
||||
installButtons = <p>{matchingInstallLinks.map((installLink) => {
|
||||
return <a
|
||||
rel="noopener noreferrer"
|
||||
aria-label={installLink.description}
|
||||
key={installLink.channelId}
|
||||
href={installLink.createInstallURL(link)}
|
||||
className="installLink"
|
||||
target="_blank">
|
||||
<img src={installBadgeImages[installLink.channelId]} alt={installLink.description} />
|
||||
</a>;
|
||||
})}</p>;
|
||||
}
|
||||
|
||||
if (client.kind === ClientKind.LINKED_CLIENT) {
|
||||
inviteButton = <Button>Accept invite</Button>;
|
||||
} else {
|
||||
|
@ -62,6 +104,7 @@ const ClientTile: React.FC<IProps> = ({ client, link }: IProps) => {
|
|||
<div>
|
||||
<h1>{client.name}</h1>
|
||||
<p>{client.description}</p>
|
||||
{installButtons}
|
||||
{inviteLine}
|
||||
{inviteButton}
|
||||
</div>
|
||||
|
@ -69,7 +112,11 @@ const ClientTile: React.FC<IProps> = ({ client, link }: IProps) => {
|
|||
);
|
||||
|
||||
if (client.kind === ClientKind.LINKED_CLIENT) {
|
||||
clientTile = <a href={client.toUrl(link).toString()}>{clientTile}</a>;
|
||||
if (!hasNativeClient) {
|
||||
clientTile = (
|
||||
<a href={client.toUrl(link).toString()}>{clientTile}</a>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return clientTile;
|
||||
|
|
7
src/imgs/app-store-us-alt.svg
Normal file
7
src/imgs/app-store-us-alt.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 13 KiB |
BIN
src/imgs/fdroid-badge.png
Normal file
BIN
src/imgs/fdroid-badge.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
41
src/imgs/google-play-us.svg
Normal file
41
src/imgs/google-play-us.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 18 KiB |
Loading…
Reference in a new issue