badges on client list and install instructions after clicking native DL
This commit is contained in:
parent
8659594c22
commit
fcf1087eaf
10 changed files with 129 additions and 8 deletions
42
css/main.css
42
css/main.css
|
@ -120,8 +120,23 @@ textarea {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a, button.text {
|
||||||
color: var(--link);
|
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 {
|
.ClientListView ul {
|
||||||
|
@ -153,3 +168,28 @@ a {
|
||||||
.ClientView .icon.element-io {
|
.ClientView .icon.element-io {
|
||||||
background-image: url('../images/client-icons/element.svg');
|
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%;
|
||||||
|
}
|
7
images/app-store-us-alt.svg
Normal file
7
images/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
images/fdroid-badge.png
Normal file
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
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 |
|
@ -22,7 +22,7 @@ export class ClientListView extends TemplateView {
|
||||||
const clients = vm.clients.map(clientViewModel => t.view(new ClientView(clientViewModel)));
|
const clients = vm.clients.map(clientViewModel => t.view(new ClientView(clientViewModel)));
|
||||||
return t.div({className: "ClientListView"}, [
|
return t.div({className: "ClientListView"}, [
|
||||||
t.h3("You need an app to continue"),
|
t.h3("You need an app to continue"),
|
||||||
t.ul({className: "ClientListView"}, clients)
|
t.div({className: "ClientListView"}, clients)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,6 @@ export class ClientListViewModel extends ViewModel {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super(options);
|
super(options);
|
||||||
const {clients, link} = 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})));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {TemplateView} from "../utils/TemplateView.js";
|
||||||
|
|
||||||
export class ClientView extends TemplateView {
|
export class ClientView extends TemplateView {
|
||||||
render(t, vm) {
|
render(t, vm) {
|
||||||
return t.li({className: "ClientView"}, [
|
return t.div({className: "ClientView"}, [
|
||||||
t.div({className: "header"}, [
|
t.div({className: "header"}, [
|
||||||
t.div({className: "description"}, [
|
t.div({className: "description"}, [
|
||||||
t.h3(vm.name),
|
t.h3(vm.name),
|
||||||
|
@ -27,7 +27,23 @@ export class ClientView extends TemplateView {
|
||||||
t.div({className: `icon ${vm.clientId}`})
|
t.div({className: `icon ${vm.clientId}`})
|
||||||
]),
|
]),
|
||||||
t.div({className: "actions"}, vm.actions.map(a => {
|
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);
|
||||||
}))
|
}))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,8 @@ export class ClientViewModel extends ViewModel {
|
||||||
label: installLink.description,
|
label: installLink.description,
|
||||||
url: installLink.createInstallURL(link),
|
url: installLink.createInstallURL(link),
|
||||||
kind: installLink.channelId,
|
kind: installLink.channelId,
|
||||||
activated() {},
|
primary: true,
|
||||||
|
activated: () => this.preferences.setClient(client.id, nativePlatform),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
actions.push(...nativeActions);
|
actions.push(...nativeActions);
|
||||||
|
@ -50,7 +51,7 @@ export class ClientViewModel extends ViewModel {
|
||||||
label: `Or open in ${client.getName(webPlatform)}`,
|
label: `Or open in ${client.getName(webPlatform)}`,
|
||||||
url: client.getDeepLink(webPlatform, link),
|
url: client.getDeepLink(webPlatform, link),
|
||||||
kind: "open-in-web",
|
kind: "open-in-web",
|
||||||
activated() {},
|
activated: () => this.preferences.setClient(client.id, webPlatform),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return actions;
|
return actions;
|
||||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import {TemplateView} from "../utils/TemplateView.js";
|
import {TemplateView} from "../utils/TemplateView.js";
|
||||||
import {ClientListView} from "../client/ClientListView.js";
|
import {ClientListView} from "../client/ClientListView.js";
|
||||||
|
import {ClientView} from "../client/ClientView.js";
|
||||||
|
|
||||||
export class PreviewView extends TemplateView {
|
export class PreviewView extends TemplateView {
|
||||||
render(t, vm) {
|
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.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)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -88,6 +88,11 @@ export class PreviewViewModel extends ViewModel {
|
||||||
const deepLink = this._preferredClient.getDeepLink(this._preferredPlatform, this._link);
|
const deepLink = this._preferredClient.getDeepLink(this._preferredPlatform, this._link);
|
||||||
this.openLink(deepLink);
|
this.openLink(deepLink);
|
||||||
// show "looks like you don't have the native app installed"
|
// 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 {
|
} else {
|
||||||
this.acceptInstructions = this._preferredClient.getLinkInstructions(this._preferredPlatform, this._link);
|
this.acceptInstructions = this._preferredClient.getLinkInstructions(this._preferredPlatform, this._link);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue