diff --git a/css/main.css b/css/main.css
index 5c2196a..16048ce 100644
--- a/css/main.css
+++ b/css/main.css
@@ -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 {
@@ -152,4 +167,29 @@ 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%;
}
\ No newline at end of file
diff --git a/images/app-store-us-alt.svg b/images/app-store-us-alt.svg
new file mode 100644
index 0000000..83437ba
--- /dev/null
+++ b/images/app-store-us-alt.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/images/fdroid-badge.png b/images/fdroid-badge.png
new file mode 100644
index 0000000..7c8c3c5
Binary files /dev/null and b/images/fdroid-badge.png differ
diff --git a/images/google-play-us.svg b/images/google-play-us.svg
new file mode 100644
index 0000000..888691a
--- /dev/null
+++ b/images/google-play-us.svg
@@ -0,0 +1,41 @@
+
\ No newline at end of file
diff --git a/src/client/ClientListView.js b/src/client/ClientListView.js
index ef3ae16..8a62cea 100644
--- a/src/client/ClientListView.js
+++ b/src/client/ClientListView.js
@@ -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)
]);
}
}
diff --git a/src/client/ClientListViewModel.js b/src/client/ClientListViewModel.js
index c998075..6cc1d47 100644
--- a/src/client/ClientListViewModel.js
+++ b/src/client/ClientListViewModel.js
@@ -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})));
}
}
diff --git a/src/client/ClientView.js b/src/client/ClientView.js
index d5c789e..3bf3784 100644
--- a/src/client/ClientView.js
+++ b/src/client/ClientView.js
@@ -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);
}))
]);
}
diff --git a/src/client/ClientViewModel.js b/src/client/ClientViewModel.js
index 1ad7c23..683c6f4 100644
--- a/src/client/ClientViewModel.js
+++ b/src/client/ClientViewModel.js
@@ -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;
diff --git a/src/preview/PreviewView.js b/src/preview/PreviewView.js
index f4c217b..ca76446 100644
--- a/src/preview/PreviewView.js
+++ b/src/preview/PreviewView.js
@@ -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)),
+ ]);
+ }
}
\ No newline at end of file
diff --git a/src/preview/PreviewViewModel.js b/src/preview/PreviewViewModel.js
index e232ca4..919e01b 100644
--- a/src/preview/PreviewViewModel.js
+++ b/src/preview/PreviewViewModel.js
@@ -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);
}