badges on client list and install instructions after clicking native DL

This commit is contained in:
Bruno Windels 2020-12-01 12:04:11 +01:00
parent 8659594c22
commit fcf1087eaf
10 changed files with 129 additions and 8 deletions

View file

@ -120,8 +120,23 @@ textarea {
padding: 0;
}
a {
a, button.text {
color: var(--link);
text-decoration: underline;
}
button.text {
background: none;
border: none;
font-style: normal;
font-weight: normal;
font-size: inherit;
padding: 8px 0;
margin: -8px 0;
}
button.text:hover {
cursor: pointer;
}
.ClientListView ul {
@ -153,3 +168,28 @@ a {
.ClientView .icon.element-io {
background-image: url('../images/client-icons/element.svg');
}
button.primary, a.primary {
background: var(--link);
color: var(--background);
border-radius: 32px;
text-decoration: none;
font-weight: bold;
}
.ClientView .actions a {
display: block;
text-align: center;
padding: 8px;
margin: 8px;
}
.ClientView .actions a.badge {
display: inline-block;
height: 40px;
margin: 8px 16px 8px 0;
}
.ClientView .actions img {
height: 100%;
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

BIN
images/fdroid-badge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

41
images/google-play-us.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -22,7 +22,7 @@ export class ClientListView extends TemplateView {
const clients = vm.clients.map(clientViewModel => t.view(new ClientView(clientViewModel)));
return t.div({className: "ClientListView"}, [
t.h3("You need an app to continue"),
t.ul({className: "ClientListView"}, clients)
t.div({className: "ClientListView"}, clients)
]);
}
}

View file

@ -22,6 +22,6 @@ export class ClientListViewModel extends ViewModel {
constructor(options) {
super(options);
const {clients, link} = options;
this.clients = clients.map(client => new ClientViewModel(this.childOptions({client, link})));
this.clients = clients.map(client => new ClientViewModel(this.childOptions({client, link, showAcceptAnyway: true})));
}
}

View file

@ -18,7 +18,7 @@ import {TemplateView} from "../utils/TemplateView.js";
export class ClientView extends TemplateView {
render(t, vm) {
return t.li({className: "ClientView"}, [
return t.div({className: "ClientView"}, [
t.div({className: "header"}, [
t.div({className: "description"}, [
t.h3(vm.name),
@ -27,7 +27,23 @@ export class ClientView extends TemplateView {
t.div({className: `icon ${vm.clientId}`})
]),
t.div({className: "actions"}, vm.actions.map(a => {
return t.a({href: a.url, className: a.kind, rel: "noopener noreferrer", onClick: () => a.activated()}, a.label);
let badgeUrl;
switch (a.kind) {
case "play-store": badgeUrl = "images/google-play-us.svg"; break;
case "fdroid": badgeUrl = "images/fdroid-badge.png"; break;
case "apple-app-store": badgeUrl = "images/app-store-us-alt.svg"; break;
}
return t.a({
href: a.url,
className: {
primary: a.primary && !badgeUrl,
secondary: !a.primary && !badgeUrl,
badge: !!badgeUrl,
},
rel: "noopener noreferrer",
["aria-label"]: a.label,
onClick: () => a.activated()
}, badgeUrl ? t.img({src: badgeUrl}) : a.label);
}))
]);
}

View file

@ -40,7 +40,8 @@ export class ClientViewModel extends ViewModel {
label: installLink.description,
url: installLink.createInstallURL(link),
kind: installLink.channelId,
activated() {},
primary: true,
activated: () => this.preferences.setClient(client.id, nativePlatform),
};
});
actions.push(...nativeActions);
@ -50,7 +51,7 @@ export class ClientViewModel extends ViewModel {
label: `Or open in ${client.getName(webPlatform)}`,
url: client.getDeepLink(webPlatform, link),
kind: "open-in-web",
activated() {},
activated: () => this.preferences.setClient(client.id, webPlatform),
});
}
return actions;

View file

@ -16,6 +16,7 @@ limitations under the License.
import {TemplateView} from "../utils/TemplateView.js";
import {ClientListView} from "../client/ClientListView.js";
import {ClientView} from "../client/ClientView.js";
export class PreviewView extends TemplateView {
render(t, vm) {
@ -31,8 +32,18 @@ export class PreviewView extends TemplateView {
]),
]),
t.p({hidden: vm => !!vm.clientsViewModel}, t.button({onClick: () => vm.accept()}, vm => vm.acceptLabel)),
t.mapView(vm => vm.clientsViewModel, vm => vm ? new ClientListView(vm) : null)
t.mapView(vm => vm.clientsViewModel, childVM => childVM ? new ClientListView(childVM) : null),
t.mapView(vm => vm.missingClientViewModel, childVM => childVM ? new MissingClientView(childVM) : null),
])
]);
}
}
class MissingClientView extends TemplateView {
render(t, vm) {
return t.div({className: "MissingClientView"}, [
t.h3(`It looks like you don't have ${vm.name} installed.`),
t.view(new ClientView(vm)),
]);
}
}

View file

@ -88,6 +88,11 @@ export class PreviewViewModel extends ViewModel {
const deepLink = this._preferredClient.getDeepLink(this._preferredPlatform, this._link);
this.openLink(deepLink);
// show "looks like you don't have the native app installed"
const protocol = new URL(deepLink).protocol;
const isWebProtocol = protocol === "http:" || protocol === "https:";
if (!isWebProtocol) {
this.missingClientViewModel = new ClientViewModel(this.childOptions({client: this._preferredClient, link: this._link}));
}
} else {
this.acceptInstructions = this._preferredClient.getLinkInstructions(this._preferredPlatform, this._link);
}