add app store install badges
This commit is contained in:
parent
c78a91ea46
commit
d484a9a423
@ -20,7 +20,9 @@ import {
|
|||||||
ClientKind,
|
ClientKind,
|
||||||
ClientId,
|
ClientId,
|
||||||
Platform,
|
Platform,
|
||||||
StoreDistribution,
|
AppleStoreLink,
|
||||||
|
PlayStoreLink,
|
||||||
|
FDroidLink
|
||||||
} from './types';
|
} from './types';
|
||||||
import { LinkKind } from '../parser/types';
|
import { LinkKind } from '../parser/types';
|
||||||
import logo from '../imgs/element.svg';
|
import logo from '../imgs/element.svg';
|
||||||
@ -61,25 +63,9 @@ export const Element: LinkedClient = {
|
|||||||
},
|
},
|
||||||
linkSupport: () => true,
|
linkSupport: () => true,
|
||||||
installLinks: [
|
installLinks: [
|
||||||
new StoreDistribution(
|
new AppleStoreLink("vector", "id1083446067"),
|
||||||
'App Store',
|
new PlayStoreLink("im.vector.app"),
|
||||||
Platform.iOS,
|
new FDroidLink("im.vector.app"),
|
||||||
'https://apps.apple.com/app/vector/id1083446067',
|
|
||||||
false
|
|
||||||
),
|
|
||||||
new StoreDistribution(
|
|
||||||
'Google Play',
|
|
||||||
Platform.Android,
|
|
||||||
'https://play.google.com/store/apps/details?id=im.vector.app',
|
|
||||||
true
|
|
||||||
),
|
|
||||||
new StoreDistribution(
|
|
||||||
'F-Droid',
|
|
||||||
Platform.Android,
|
|
||||||
'https://f-droid.org/fr/packages/im.vector.app/',
|
|
||||||
false
|
|
||||||
),
|
|
||||||
// TODO desktop clients?
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,22 +57,73 @@ export enum ClientId {
|
|||||||
* Define a native distribution channel for a client.
|
* Define a native distribution channel for a client.
|
||||||
* E.g App store for apple, PlayStore or F-Droid for Android
|
* E.g App store for apple, PlayStore or F-Droid for Android
|
||||||
*/
|
*/
|
||||||
export class StoreDistribution {
|
export interface InstallLink {
|
||||||
public name: string;
|
createInstallURL(deepLink: SafeLink) : string;
|
||||||
public platform: Platform;
|
//get buttonCSSClass(): string;
|
||||||
public download: string;
|
platform: Platform;
|
||||||
public supportReferrer: boolean;
|
// in AppleStoreLink, we can set the cookie here
|
||||||
|
// onInstallChosen(deepLink: SafeLink);
|
||||||
|
channelId: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(
|
export class AppleStoreLink implements InstallLink {
|
||||||
name: string,
|
constructor(private org: string, private appId: string) {}
|
||||||
platform: Platform,
|
|
||||||
download: string,
|
createInstallURL(deepLink: SafeLink) : string {
|
||||||
supportReferrer: boolean
|
return `https://apps.apple.com/app/${encodeURIComponent(this.org)}/${encodeURIComponent(this.appId)}`;
|
||||||
) {
|
}
|
||||||
this.name = name;
|
|
||||||
this.platform = platform;
|
get platform() : Platform {
|
||||||
this.download = download;
|
return Platform.iOS;
|
||||||
this.supportReferrer = supportReferrer;
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +141,7 @@ export interface ClientDescription {
|
|||||||
clientId: ClientId;
|
clientId: ClientId;
|
||||||
experimental: boolean;
|
experimental: boolean;
|
||||||
linkSupport: (link: SafeLink) => boolean;
|
linkSupport: (link: SafeLink) => boolean;
|
||||||
installLinks: StoreDistribution[];
|
installLinks: InstallLink[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -67,6 +67,15 @@ limitations under the License.
|
|||||||
&:hover {
|
&:hover {
|
||||||
background-color: $app-background;
|
background-color: $app-background;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.installLink {
|
||||||
|
display: inline-block;
|
||||||
|
height: 40px;
|
||||||
|
margin: 8px 16px 8px 0;
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.clientTileLink {
|
.clientTileLink {
|
||||||
|
@ -23,6 +23,10 @@ import { SafeLink } from '../parser/types';
|
|||||||
import Tile from './Tile';
|
import Tile from './Tile';
|
||||||
import Button from './Button';
|
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';
|
import './ClientTile.scss';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
@ -30,6 +34,16 @@ interface IProps {
|
|||||||
link: SafeLink;
|
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 ClientTile: React.FC<IProps> = ({ client, link }: IProps) => {
|
||||||
const inviteLine =
|
const inviteLine =
|
||||||
client.kind === ClientKind.TEXT_CLIENT ? (
|
client.kind === ClientKind.TEXT_CLIENT ? (
|
||||||
@ -43,47 +57,32 @@ const ClientTile: React.FC<IProps> = ({ client, link }: IProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let inviteButton: JSX.Element = <></>;
|
let inviteButton: JSX.Element = <></>;
|
||||||
let hasNativeClient = false;
|
const matchingInstallLinks = client.installLinks.filter((installLink) => {
|
||||||
let installButton = undefined;
|
|
||||||
if (client.kind === ClientKind.LINKED_CLIENT) {
|
|
||||||
const availableClients = client.installLinks.filter((distrib) => {
|
|
||||||
if ((uaResults as any).ios) {
|
if ((uaResults as any).ios) {
|
||||||
return distrib.platform == Platform.iOS;
|
return installLink.platform === Platform.iOS;
|
||||||
} else if ((uaResults as any).android) {
|
} else if ((uaResults as any).android) {
|
||||||
return distrib.platform == Platform.Android;
|
return installLink.platform === Platform.Android;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
hasNativeClient = availableClients.length > 0;
|
const hasNativeClient = matchingInstallLinks.length > 0;
|
||||||
if (hasNativeClient) {
|
let installButtons = undefined;
|
||||||
inviteButton = (
|
if (matchingInstallLinks.length) {
|
||||||
<Button
|
installButtons = <p>{matchingInstallLinks.map((installLink) => {
|
||||||
onClick={() => window.open('matrix://' + link.originalLink)}
|
return <a
|
||||||
>
|
rel="noopener noreferrer"
|
||||||
Accept invite
|
key={installLink.channelId}
|
||||||
</Button>
|
href={installLink.createInstallURL(link)}
|
||||||
);
|
className="installLink"
|
||||||
} else {
|
target="_blank">
|
||||||
inviteButton = <Button>Accept invite</Button>;
|
<img src={installBadgeImages[installLink.channelId]} alt={installLink.description} />
|
||||||
|
</a>;
|
||||||
|
})}</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
installButton = availableClients.map((distrib) => (
|
if (client.kind === ClientKind.LINKED_CLIENT) {
|
||||||
<Button
|
inviteButton = <Button>Accept invite</Button>;
|
||||||
onClick={() =>
|
|
||||||
window.open(
|
|
||||||
distrib.supportReferrer
|
|
||||||
? distrib.download +
|
|
||||||
'&referrer=' +
|
|
||||||
link.originalLink
|
|
||||||
: distrib.download,
|
|
||||||
'_blank'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Get it on {distrib.name}
|
|
||||||
</Button>
|
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
const copyString = client.copyString(link);
|
const copyString = client.copyString(link);
|
||||||
if (copyString !== '') {
|
if (copyString !== '') {
|
||||||
@ -104,8 +103,8 @@ const ClientTile: React.FC<IProps> = ({ client, link }: IProps) => {
|
|||||||
<div>
|
<div>
|
||||||
<h1>{client.name}</h1>
|
<h1>{client.name}</h1>
|
||||||
<p>{client.description}</p>
|
<p>{client.description}</p>
|
||||||
|
{installButtons}
|
||||||
{inviteLine}
|
{inviteLine}
|
||||||
{hasNativeClient && installButton}
|
|
||||||
{inviteButton}
|
{inviteButton}
|
||||||
</div>
|
</div>
|
||||||
</Tile>
|
</Tile>
|
||||||
|
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 New Issue
Block a user