improve text instructions and copy button
This commit is contained in:
parent
e5743471f4
commit
166f5ded77
7 changed files with 60 additions and 24 deletions
|
@ -60,3 +60,24 @@
|
||||||
.ClientView .actions img {
|
.ClientView .actions img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.InstallClientView .instructions button {
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-color: var(--link);
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: none;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin: 8px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.InstallClientView .instructions button.copy {
|
||||||
|
background-image: url('../images/copy.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.InstallClientView .instructions button.tick {
|
||||||
|
background-image: url('../images/tick.svg');
|
||||||
|
}
|
||||||
|
|
|
@ -55,7 +55,8 @@ export class ClientListViewModel extends ViewModel {
|
||||||
|
|
||||||
_filterClients() {
|
_filterClients() {
|
||||||
this.clientList = this._clients.filter(client => {
|
this.clientList = this._clients.filter(client => {
|
||||||
const isStable = this.platforms.map(p => client.getMaturity(p)).includes(Maturity.Stable);
|
const platformMaturities = this.platforms.map(p => client.getMaturity(p));
|
||||||
|
const isStable = platformMaturities.includes(Maturity.Stable) || platformMaturities.includes(Maturity.Beta);
|
||||||
const isSupported = client.platforms.some(p => this.platforms.includes(p));
|
const isSupported = client.platforms.some(p => this.platforms.includes(p));
|
||||||
if (!this._showExperimental && !isStable) {
|
if (!this._showExperimental && !isStable) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {TemplateView} from "../utils/TemplateView.js";
|
import {TemplateView} from "../utils/TemplateView.js";
|
||||||
import {copyButton} from "../utils/copy.js";
|
import {copy} from "../utils/copy.js";
|
||||||
import {text} from "../utils/html.js";
|
import {text} from "../utils/html.js";
|
||||||
|
|
||||||
function formatPlatforms(platforms) {
|
function formatPlatforms(platforms) {
|
||||||
|
@ -66,11 +66,19 @@ class InstallClientView extends TemplateView {
|
||||||
const children = [];
|
const children = [];
|
||||||
|
|
||||||
if (vm.textInstructions) {
|
if (vm.textInstructions) {
|
||||||
children.push(t.p({}, vm.textInstructions));
|
const copyButton = t.button({
|
||||||
if (vm.copyString) {
|
className: "copy",
|
||||||
children.push(t.p(copyButton(t, () => vm.copyString, "Copy invite", "fullwidth primary")));
|
onClick: evt => {
|
||||||
|
if (copy(vm.copyString, copyButton.parentElement)) {
|
||||||
|
copyButton.className = "tick";
|
||||||
|
setTimeout(() => {
|
||||||
|
copyButton.className = "copy";
|
||||||
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
children.push(t.p({className: "instructions"}, [vm.textInstructions, copyButton]));
|
||||||
|
}
|
||||||
|
|
||||||
const actions = t.div({className: "actions"}, vm.actions.map(a => {
|
const actions = t.div({className: "actions"}, vm.actions.map(a => {
|
||||||
let badgeUrl;
|
let badgeUrl;
|
||||||
|
@ -78,6 +86,7 @@ class InstallClientView extends TemplateView {
|
||||||
case "play-store": badgeUrl = "images/google-play-us.svg"; break;
|
case "play-store": badgeUrl = "images/google-play-us.svg"; break;
|
||||||
case "fdroid": badgeUrl = "images/fdroid-badge.png"; break;
|
case "fdroid": badgeUrl = "images/fdroid-badge.png"; break;
|
||||||
case "apple-app-store": badgeUrl = "images/app-store-us-alt.svg"; break;
|
case "apple-app-store": badgeUrl = "images/app-store-us-alt.svg"; break;
|
||||||
|
case "flathub": badgeUrl = "images/flathub-badge.svg"; break;
|
||||||
}
|
}
|
||||||
return t.a({
|
return t.a({
|
||||||
href: a.url,
|
href: a.url,
|
||||||
|
|
|
@ -67,7 +67,6 @@ export class ClientViewModel extends ViewModel {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (actions.length === 0) {
|
|
||||||
actions.push({
|
actions.push({
|
||||||
label: `Visit app homepage`,
|
label: `Visit app homepage`,
|
||||||
url: client.homepage,
|
url: client.homepage,
|
||||||
|
@ -75,7 +74,6 @@ export class ClientViewModel extends ViewModel {
|
||||||
kind: "homepage",
|
kind: "homepage",
|
||||||
activated: () => {},
|
activated: () => {},
|
||||||
});
|
});
|
||||||
}
|
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import {Maturity, Platform, LinkKind, WebsiteLink} from "../types.js";
|
||||||
* Information on how to deep link to a given matrix client.
|
* Information on how to deep link to a given matrix client.
|
||||||
*/
|
*/
|
||||||
export class Weechat {
|
export class Weechat {
|
||||||
/* should only contain alphanumerical and -_, no dots (needs to be usable as css class) */
|
|
||||||
get id() { return "weechat"; }
|
get id() { return "weechat"; }
|
||||||
getName(platform) { return "Weechat"; }
|
getName(platform) { return "Weechat"; }
|
||||||
get icon() { return "images/client-icons/weechat.svg"; }
|
get icon() { return "images/client-icons/weechat.svg"; }
|
||||||
|
|
|
@ -16,10 +16,14 @@ limitations under the License.
|
||||||
|
|
||||||
import {Element} from "./Element.js";
|
import {Element} from "./Element.js";
|
||||||
import {Weechat} from "./Weechat.js";
|
import {Weechat} from "./Weechat.js";
|
||||||
|
import {Nheko} from "./Nheko.js";
|
||||||
|
import {Fractal} from "./Fractal.js";
|
||||||
|
|
||||||
export function createClients() {
|
export function createClients() {
|
||||||
return [
|
return [
|
||||||
new Element(),
|
new Element(),
|
||||||
new Weechat(),
|
new Weechat(),
|
||||||
|
new Nheko(),
|
||||||
|
new Fractal(),
|
||||||
];
|
];
|
||||||
}
|
}
|
|
@ -22,15 +22,20 @@ function selectNode(node) {
|
||||||
selection.addRange(range);
|
selection.addRange(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function copy(text, parent) {
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.innerText = text;
|
||||||
|
parent.appendChild(span);
|
||||||
|
selectNode(span);
|
||||||
|
const result = document.execCommand("copy");
|
||||||
|
parent.removeChild(span);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export function copyButton(t, getCopyText, label, classNames) {
|
export function copyButton(t, getCopyText, label, classNames) {
|
||||||
return t.button({className: `${classNames} icon copy`, onClick: evt => {
|
return t.button({className: `${classNames} icon copy`, onClick: evt => {
|
||||||
const button = evt.target;
|
const button = evt.target;
|
||||||
const text = getCopyText();
|
if (copy(getCopyText(), button)) {
|
||||||
const span = document.createElement("span");
|
|
||||||
span.innerText = text;
|
|
||||||
button.parentElement.appendChild(span);
|
|
||||||
selectNode(span);
|
|
||||||
if (document.execCommand("copy")) {
|
|
||||||
button.innerText = "Copied!";
|
button.innerText = "Copied!";
|
||||||
button.classList.remove("copy");
|
button.classList.remove("copy");
|
||||||
button.classList.add("tick");
|
button.classList.add("tick");
|
||||||
|
@ -40,6 +45,5 @@ export function copyButton(t, getCopyText, label, classNames) {
|
||||||
button.innerText = label;
|
button.innerText = label;
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
span.parentElement.removeChild(span);
|
|
||||||
}}, label);
|
}}, label);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue