Skip to content

Commit

Permalink
steps are reactive
Browse files Browse the repository at this point in the history
  • Loading branch information
onmax committed Jan 31, 2022
1 parent 35c1b32 commit 7ecc535
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 161 deletions.
6 changes: 4 additions & 2 deletions src/components/TourLargeScreenManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export default defineComponent({
original.style.visibility = 'initial';
}
// at some steps, a modal will be openened in the tour and we still need to show the tour
// manager to the user, therefore, we need to duplicate the manager and set it to the body
// positionated over the modal
function _duplicateManager() {
_removeClonedManager();
const original = $originalManager.value!;
Expand All @@ -69,8 +72,7 @@ export default defineComponent({
}
manager.style.position = 'absolute';
// manager.style.top = `${original.offsetTop}px`; // FIXME: it is getting 114px instead of 98px
manager.style.top = '98px';
manager.style.top = `${original.offsetTop - 16}px`; // TODO Test this with other announcements
manager.style.left = `${original.offsetLeft}px`;
manager.style.width = `${original.offsetWidth}px`;
manager.style.height = `${original.offsetHeight}px`;
Expand Down
4 changes: 2 additions & 2 deletions src/components/layouts/Network.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ const LOCALSTORAGE_KEY = 'network-info-dismissed';
export default defineComponent({
setup(props, context) {
const showNetworkInfo = ref(true // TOOD Remove me
|| !window.localStorage.getItem(LOCALSTORAGE_KEY) || !!context.root.$route.params.showNetworkInfo);
const showNetworkInfo = ref(
!window.localStorage.getItem(LOCALSTORAGE_KEY) || !!context.root.$route.params.showNetworkInfo);
function onNetworkInfoClosed() {
window.localStorage.setItem(LOCALSTORAGE_KEY, '1');
Expand Down
6 changes: 3 additions & 3 deletions src/components/modals/DiscoverTheNimiqWalletModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<div class="content">
<div class="description">
<GreenNimiqLogoOutlineWithStars />
<NimiqLogoOutlineWithStars />
<h1 class="nq-h1">{{ $t('Discover the Nimiq Wallet!') }}</h1>
<p class="nq-text">
{{ $t('It\'s free, does not collect data and is controlled by no one but you.') }}
Expand Down Expand Up @@ -43,7 +43,7 @@ import { PageHeader } from '@nimiq/vue-components';
import { defineComponent } from '@vue/composition-api';
import { TourName } from '@/lib/tour';
import { Languages } from '../../i18n/i18n-setup';
import GreenNimiqLogoOutlineWithStars from '../icons/GreenNimiqLogoOutlineWithStars.vue';
import NimiqLogoOutlineWithStars from '../icons/NimiqLogoOutlineWithStars.vue';
import CaretRightIcon from '../icons/CaretRightIcon.vue';
import Modal from './Modal.vue';
Expand Down Expand Up @@ -73,7 +73,7 @@ export default defineComponent({
components: {
Modal,
PageHeader,
GreenNimiqLogoOutlineWithStars,
NimiqLogoOutlineWithStars,
CaretRightIcon,
},
});
Expand Down
88 changes: 38 additions & 50 deletions src/lib/tour/onboarding/01_FirstAddressStep.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { CryptoCurrency } from '@/lib/Constants';
import { useAccountStore } from '@/stores/Account';
import { useAddressStore } from '@/stores/Address';
import { GetStepFnArgs, OnboardingTourStep, TourStep, WalletHTMLElements } from '../types';
import { OnboardingGetStepFnArgs, OnboardingTourStep, TourStep, WalletHTMLElements } from '../types';
import { getOnboardingTexts } from './OnboardingTourTexts';

export function getFirstAddressStep(
{ isSmallScreen, isANewUser, root }: GetStepFnArgs<OnboardingTourStep>): TourStep {
{ isSmallScreen, isANewUser, root }: OnboardingGetStepFnArgs): TourStep {
const created = () => {
const { setActiveCurrency } = useAccountStore();
const { addressInfos, selectAddress } = useAddressStore();
Expand Down Expand Up @@ -43,63 +43,51 @@ export function getFirstAddressStep(
],
};

if (isSmallScreen.value) {
return {
path,
tooltip: {
target: `${WalletHTMLElements.ACCOUNT_OVERVIEW_ADDRESS_LIST} .address-button .identicon img`,
content: getOnboardingTexts(OnboardingTourStep.FIRST_ADDRESS, isANewUser).default,
params: {
placement: 'bottom-start',
},
},
lifecycle: {
created,
mounted: ({ goToNextStep }) => {
if (!isSmallScreen.value) {
return undefined;
}

// Listener for the first address button only for mobile

const addressButton = document
.querySelector('.address-list > .address-button') as HTMLButtonElement;

let addressClicked = false;
const onClick = (e: MouseEvent) => {
addressClicked = true;
goToNextStep();
e.preventDefault();
e.stopPropagation();
};

addressButton!.addEventListener('click', onClick, { once: true, capture: true });

return async (args) => {
if (!args?.ending && !addressClicked && root.$route.path === path) {
addressButton!.click();
await root.$nextTick();
}
addressButton!.removeEventListener('click', onClick, true);
};
},
},
ui,
} as TourStep;
}

// Not mobile
return {
path,
tooltip: {
target: `${WalletHTMLElements.ADDRESS_OVERVIEW_ACTIVE_ADDRESS} .identicon`,
get target() {
return isSmallScreen.value
? `${WalletHTMLElements.ACCOUNT_OVERVIEW_ADDRESS_LIST} .address-button .identicon img`
: `${WalletHTMLElements.ADDRESS_OVERVIEW_ACTIVE_ADDRESS} .identicon`;
},
content: getOnboardingTexts(OnboardingTourStep.FIRST_ADDRESS, isANewUser).default,
params: {
placement: 'left-start',
get placement() {
return isSmallScreen.value ? 'bottom-start' : 'left-start';
},
},
},
lifecycle: {
created,
mounted: ({ goToNextStep }) => {
if (!isSmallScreen.value) {
return undefined;
}

// Listener for the first address button only for mobile

const addressButton = document
.querySelector('.address-list > .address-button') as HTMLButtonElement;

let addressClicked = false;
const onClick = (e: MouseEvent) => {
addressClicked = true;
goToNextStep();
e.preventDefault();
e.stopPropagation();
};

addressButton!.addEventListener('click', onClick, { once: true, capture: true });

return async (args) => {
if (!args?.ending && !addressClicked && root.$route.path === path) {
addressButton!.click();
await root.$nextTick();
}
addressButton!.removeEventListener('click', onClick, true);
};
},
},
ui,
} as TourStep;
Expand Down
102 changes: 44 additions & 58 deletions src/lib/tour/onboarding/02_TransactionListStep.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,18 @@
import { useTransactionsStore } from '@/stores/Transactions';
import { WalletHTMLElements } from '..';
import { GetStepFnArgs, OnboardingTourStep, TourStep } from '../types';
import { OnboardingGetStepFnArgs, OnboardingTourStep, TourStep } from '../types';
import { getOnboardingTexts } from './OnboardingTourTexts';

export function getTransactionListStep(
{ root, steps, isSmallScreen, isANewUser }: GetStepFnArgs<OnboardingTourStep>): TourStep {
const txs = useTransactionsStore().state.transactions;
const startsWithNoTransactions = Object.values(txs).length === 0;
{ isSmallScreen, isANewUser }: OnboardingGetStepFnArgs): TourStep {
const txsLen = () => Object.values(useTransactionsStore().state.transactions).length;

const tooltipWhenNoTx: TourStep['tooltip'] = {
target: isSmallScreen.value
? `${WalletHTMLElements.ADDRESS_OVERVIEW_TRANSACTIONS} > .empty-state h2`
: WalletHTMLElements.ADDRESS_OVERVIEW,
content: getOnboardingTexts(OnboardingTourStep.TRANSACTIONS_LIST, isANewUser).default,
params: {
placement: isSmallScreen.value ? 'top' : 'left',
},
};
const tooltipWhenAtLeastOneTx: TourStep['tooltip'] = {
target: isSmallScreen.value
? '.vue-recycle-scroller__item-wrapper'
: WalletHTMLElements.ADDRESS_OVERVIEW,
content: getOnboardingTexts(OnboardingTourStep.TRANSACTIONS_LIST, isANewUser).alternative || [],
params: {
placement: isSmallScreen.value ? 'bottom' : 'left',
},
};

let userHasClicked = false;
const highlightButton = (highlight: boolean) => {
if (userHasClicked) return;

const receiveNim = document
.querySelector(WalletHTMLElements.BUTTON_ADDRESS_OVERVIEW_RECEIVE_FREE_NIM) as HTMLButtonElement;
if (!receiveNim) return;
receiveNim.classList[highlight ? 'add' : 'remove']('highlighted');
};
const mounted = () => {
const { transactions } = useTransactionsStore().state;

if (Object.values(transactions.value || []).length === 0) {
const unwatch = root.$watch(() => txs, () => {
if (!Object.values(txs).length) {
unwatch();
return;
}

userHasClicked = true;

const buyNimBtn = document
.querySelector(`${WalletHTMLElements.ADDRESS_OVERVIEW_TRANSACTIONS} a button`) as HTMLButtonElement;
buyNimBtn.disabled = true;

// Once the user has at least one transaction, step TRANSACTIONS_LIST is modified
steps[OnboardingTourStep.TRANSACTIONS_LIST]!.tooltip = tooltipWhenAtLeastOneTx;
steps[OnboardingTourStep.TRANSACTIONS_LIST]!.ui.isNextStepDisabled = false;
steps[OnboardingTourStep.TRANSACTIONS_LIST]!.lifecycle = {};

unwatch();
});
}
highlightButton(true);
return () => highlightButton(false);
};

const ui: TourStep['ui'] = {
fadedElements: [
Expand Down Expand Up @@ -92,13 +42,49 @@ export function getTransactionListStep(
WalletHTMLElements.BUTTON_SIDEBAR_SELL,
WalletHTMLElements.BUTTON_ADDRESS_OVERVIEW_BUY,
],
isNextStepDisabled: startsWithNoTransactions,
};

return {
path: isSmallScreen.value ? '/transactions' : '/',
tooltip: startsWithNoTransactions ? tooltipWhenNoTx : tooltipWhenAtLeastOneTx,
lifecycle: startsWithNoTransactions ? { mounted } : {},
ui,
get path() {
return isSmallScreen.value ? '/transactions' : '/';
},
tooltip: {
get target() {
if (txsLen() > 0) {
return isSmallScreen.value
? `${WalletHTMLElements.ADDRESS_OVERVIEW_TRANSACTIONS} .vue-recycle-scroller__item-wrapper`
: WalletHTMLElements.ADDRESS_OVERVIEW;
}
return isSmallScreen.value
? `${WalletHTMLElements.ADDRESS_OVERVIEW_TRANSACTIONS} > .empty-state h2`
: WalletHTMLElements.ADDRESS_OVERVIEW;
},
get content() {
return txsLen() > 0
? getOnboardingTexts(OnboardingTourStep.TRANSACTION_LIST, isANewUser).alternative || []
: getOnboardingTexts(OnboardingTourStep.TRANSACTION_LIST, isANewUser).default || [];
},
params: {
get placement() {
if (txsLen() > 0) {
return isSmallScreen.value ? 'bottom' : 'left';
}
return isSmallScreen.value ? 'top' : 'left';
},
},
},
lifecycle: {
mounted: () => {
if (txsLen() > 0) return undefined;
highlightButton(true);
return () => highlightButton(false);
},
},
get ui() {
return {
...ui,
isNextStepDisabled: txsLen() === 0,
};
},
};
}
20 changes: 13 additions & 7 deletions src/lib/tour/onboarding/03_FirstTransactionStep.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { WalletHTMLElements } from '..';
import { GetStepFnArgs, OnboardingTourStep, TourStep } from '../types';
import { OnboardingGetStepFnArgs, OnboardingTourStep, TourStep } from '../types';
import { getOnboardingTexts } from './OnboardingTourTexts';

export function getFirstTransactionStep({ isSmallScreen, isANewUser }: GetStepFnArgs<OnboardingTourStep>): TourStep {
export function getFirstTransactionStep({ isSmallScreen, isANewUser }: OnboardingGetStepFnArgs): TourStep {
const ui: TourStep['ui'] = {
fadedElements: [
WalletHTMLElements.SIDEBAR_TESTNET,
Expand Down Expand Up @@ -31,14 +31,20 @@ export function getFirstTransactionStep({ isSmallScreen, isANewUser }: GetStepFn
};

return {
path: isSmallScreen.value ? '/transactions' : '/',
get path() {
return isSmallScreen.value ? '/transactions' : '/';
},
tooltip: {
target: isSmallScreen.value
? `${WalletHTMLElements.ADDRESS_OVERVIEW_TRANSACTIONS} .transaction > .identicon`
: `${WalletHTMLElements.ADDRESS_OVERVIEW} .vue-recycle-scroller__item-view:nth-child(2)`,
get target() {
return isSmallScreen.value
? `${WalletHTMLElements.ADDRESS_OVERVIEW_TRANSACTIONS} .transaction > .identicon`
: `${WalletHTMLElements.ADDRESS_OVERVIEW} .vue-recycle-scroller__item-view:nth-child(2)`;
},
content: getOnboardingTexts(OnboardingTourStep.FIRST_TRANSACTION, isANewUser).default,
params: {
placement: isSmallScreen.value ? 'bottom-start' : 'left',
get placement() {
return isSmallScreen.value ? 'bottom-start' : 'left';
},
},
},
ui,
Expand Down
16 changes: 10 additions & 6 deletions src/lib/tour/onboarding/04_BitcoinAddressStep.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { GetStepFnArgs, OnboardingTourStep, TourStep, WalletHTMLElements } from '../types';
import { OnboardingGetStepFnArgs, OnboardingTourStep, TourStep, WalletHTMLElements } from '../types';
import { getOnboardingTexts } from './OnboardingTourTexts';

export function getBitcoinAddressStep(
{ isSmallScreen, isMediumScreen, isANewUser }: GetStepFnArgs<OnboardingTourStep>): TourStep {
{ isLargeScreen, isANewUser }: OnboardingGetStepFnArgs): TourStep {
const ui: TourStep['ui'] = {
fadedElements: [
WalletHTMLElements.SIDEBAR_TESTNET,
Expand Down Expand Up @@ -33,12 +33,16 @@ export function getBitcoinAddressStep(
return {
path: '/',
tooltip: {
target: `.account-overview .bitcoin-account ${isSmallScreen.value || isMediumScreen.value
? '> .bitcoin-account-item > svg' : ''}`,
get target() {
return `.account-overview .bitcoin-account ${!isLargeScreen.value
? '> .bitcoin-account-item > svg' : ''}`;
},
content: getOnboardingTexts(OnboardingTourStep.BITCOIN_ADDRESS, isANewUser).default,
params: {
placement: isSmallScreen.value || isMediumScreen.value ? 'top-start' : 'right-end',
// TODO Add margin in large screens
get placement() {
// TODO Add margin in large screens
return !isLargeScreen.value ? 'bottom-start' : 'left';
},
},
},
ui,
Expand Down
14 changes: 9 additions & 5 deletions src/lib/tour/onboarding/05_WalletBalanceStep.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GetStepFnArgs, OnboardingTourStep, TourStep, WalletHTMLElements } from '../types';
import { OnboardingGetStepFnArgs, OnboardingTourStep, TourStep, WalletHTMLElements } from '../types';
import { getOnboardingTexts } from './OnboardingTourTexts';

export function getWalletBalanceStep({ isSmallScreen, isANewUser }: GetStepFnArgs<OnboardingTourStep>): TourStep {
export function getWalletBalanceStep({ isSmallScreen, isANewUser }: OnboardingGetStepFnArgs): TourStep {
const ui: TourStep['ui'] = {
fadedElements: [
WalletHTMLElements.SIDEBAR_TESTNET,
Expand Down Expand Up @@ -32,11 +32,15 @@ export function getWalletBalanceStep({ isSmallScreen, isANewUser }: GetStepFnArg
return {
path: '/',
tooltip: {
target: `${WalletHTMLElements.ACCOUNT_OVERVIEW_BALANCE}
${isSmallScreen.value ? '.amount' : '.balance-distribution'}`,
get target() {
return `${WalletHTMLElements.ACCOUNT_OVERVIEW_BALANCE}
${isSmallScreen.value ? '.amount' : '.balance-distribution'}`;
},
content: getOnboardingTexts(OnboardingTourStep.WALLET_BALANCE, isANewUser).default,
params: {
placement: isSmallScreen.value ? 'bottom' : 'right',
get placement() {
return isSmallScreen.value ? 'bottom' : 'right';
},
},
},
ui,
Expand Down
Loading

0 comments on commit 7ecc535

Please sign in to comment.