Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into onmax/tour
Browse files Browse the repository at this point in the history
  • Loading branch information
onmax committed Jan 24, 2022
2 parents 3f22464 + 0fd0d6b commit 492d602
Show file tree
Hide file tree
Showing 44 changed files with 1,217 additions and 962 deletions.
4 changes: 3 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,viewport-fit=cover">
<meta name="theme-color" content="white" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#1f2348" media="(prefers-color-scheme: dark)">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>Nimiq Wallet</title>
<link href="https://fonts.googleapis.com/css?family=Muli:400,600,700" rel="stylesheet">
Expand Down
52 changes: 14 additions & 38 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Tour/>
</transition>

<main :class="routeClass" ref="$main">
<main :class="activeMobileColumn" ref="$main">
<Sidebar/>

<transition name="delay">
Expand All @@ -32,50 +32,22 @@
<script lang="ts">
import { defineComponent, ref, watch, computed, onMounted, Ref } from '@vue/composition-api';
import { LoadingSpinner } from '@nimiq/vue-components';
import Sidebar from './components/layouts/Sidebar.vue';
import SwapNotification from './components/swap/SwapNotification.vue';
import UpdateNotification from './components/UpdateNotification.vue';
import router, { provideRouter, Columns } from './router';
import router, { provideRouter } from './router';
import { useAccountStore } from './stores/Account';
import { useSettingsStore } from './stores/Settings';
import { useWindowSize } from './composables/useWindowSize';
import { useActiveMobileColumn } from './composables/useActiveMobileColumn';
import { useSwipes } from './composables/useSwipes';
export default defineComponent({
name: 'app',
setup(props, context) {
provideRouter(router);
const routeClass = ref('');
watch(() => context.root.$route.meta, (meta) => {
if (!meta) return;
// Using a watcher, because the routeClass should only change when a route is visited
// that may require a column navigation. When opening modals, we don't want to change
// column.
switch (meta.column) {
case Columns.DYNAMIC:
switch (context.root.$route.path) {
case '/': routeClass.value = 'column-account'; break;
case '/transactions': routeClass.value = 'column-address'; break;
default: break; // Don't change column
}
break;
case Columns.ACCOUNT: routeClass.value = 'column-account'; break;
case Columns.ADDRESS: routeClass.value = 'column-address'; break;
default: break;
}
});
watch(() => context.root.$route.query, (newQuery, oldQuery) => {
if (!newQuery) return;
if (newQuery.sidebar) {
routeClass.value = 'column-sidebar';
} else if (oldQuery && oldQuery.sidebar) {
routeClass.value = 'column-account';
}
});
const { activeMobileColumn } = useActiveMobileColumn();
const { accountInfos, state: accountState, setTour } = useAccountStore();
if (!['root', 'transactions'].includes(context.root.$route.name as string)
Expand All @@ -92,7 +64,7 @@ export default defineComponent({
// Swiping
const $main = ref<HTMLDivElement>(null);
let $mobileTapArea: HTMLDivElement | null = null;
const { width } = useWindowSize();
const { width, isMobile } = useWindowSize();
async function updateSwipeRestPosition(
velocityDistance: number,
Expand Down Expand Up @@ -161,23 +133,23 @@ export default defineComponent({
excludeSelector: '.scroller, .scroller *',
});
watch([width, swipingEnabled], ([newWidth, newSwiping], [oldWidth, oldSwiping]) => {
watch([isMobile, swipingEnabled], ([isMobileNow, newSwiping], [wasMobile, oldSwiping]) => {
if (!$main.value) return;
if ((newWidth <= 700 && oldWidth > 700) || (newSwiping === 1 && oldSwiping !== 1)) {
if ((isMobileNow && !wasMobile) || (newSwiping === 1 && oldSwiping !== 1)) {
attachSwipe();
} else if (newWidth > 700 || newSwiping !== 1) {
} else if (!isMobileNow || newSwiping !== 1) {
detachSwipe();
}
}, { lazy: true });
onMounted(() => {
if (width.value <= 700 && swipingEnabled.value === 1) attachSwipe();
if (isMobile.value && swipingEnabled.value === 1) attachSwipe();
});
return {
showTour,
routeClass,
activeMobileColumn,
hasAccounts,
amountsHidden,
$main,
Expand Down Expand Up @@ -373,6 +345,10 @@ body {
display: block;
}
.nq-card {
padding-bottom: env(safe-area-inset-bottom);
}
.fade-enter-active, .fade-leave-active {
transition: opacity var(--transition-time) cubic-bezier(0.5, 0, 0.15, 1);
Expand Down
4 changes: 2 additions & 2 deletions src/components/AccountBalance.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ export default defineComponent({
const $fiatAmountContainer = ref<HTMLDivElement>(null);
const $fiatAmount = ref<Vue>(null);
const { width: windowWidth } = useWindowSize();
const fiatAmountMaxSize = computed(() => windowWidth.value > 1160 ? 7 : 5.5); // rem
const { isFullDesktop } = useWindowSize();
const fiatAmountMaxSize = computed(() => isFullDesktop.value ? 7 : 5.5); // rem
const fiatAmountFontSize = ref(fiatAmountMaxSize.value);
async function updateFontSize() {
Expand Down
22 changes: 14 additions & 8 deletions src/components/AddressList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,6 @@
:class="{ 'active': activeAddress === addressInfo.address && activeCurrency === CryptoCurrency.NIM }"
@click="selectAddress(addressInfo.address);"
:ref="`address-button-${addressInfo.address}`"/>
<hr class="separator" v-if="showBitcoin"/>
<AddressListItem
v-if="showBitcoin"
:addressInfo="btcInfos"
:class="{ 'active': activeCurrency === CryptoCurrency.BTC }"
@click="selectBtcAddress()"
:ref="`address-button-${btcInfos.address}`"/>
<button
v-if="showAddAddressButton"
class="address-button add-address-button reset flex-row"
Expand All @@ -24,12 +17,19 @@
</div>
<span class="label add-address-label">{{ $t('Add\u00a0address') }}</span>
</button>
<div class="scroll-mask bottom"></div>
<hr class="separator" v-if="showBitcoin"/>
<AddressListItem
v-if="showBitcoin"
:addressInfo="btcInfos"
:class="{ 'active': activeCurrency === CryptoCurrency.BTC }"
@click="selectBtcAddress()"
:ref="`address-button-${btcInfos.address}`"/>
<div v-if="!embedded"
class="active-box"
:class="{ enabled: activeCurrency === CryptoCurrency.NIM }"
:style="`--backgroundYScale: ${backgroundYScale}; --backgroundYOffset: ${backgroundYOffset}px`"
></div>
<div class="scroll-mask bottom"></div>
</div>
</template>

Expand Down Expand Up @@ -212,6 +212,7 @@ export default defineComponent({
}
.address-list {
height: 100%;
display: flex;
flex-direction: column;
position: relative;
Expand All @@ -230,6 +231,7 @@ export default defineComponent({
hr.separator {
margin: 15px 0 15px 0;
margin-top: auto;
border-top: 1.5px solid var(--nimiq-blue);
opacity: 0.14;
}
Expand Down Expand Up @@ -379,5 +381,9 @@ export default defineComponent({
.add-address-button {
padding: 1.5rem;
}
.embedded ::v-deep .mobile-arrow {
display: inherit;
}
}
</style>
6 changes: 1 addition & 5 deletions src/components/BalanceDistribution.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,12 @@ import { useSwapsStore } from '../stores/Swaps';
export default defineComponent({
name: 'balance-distribution',
setup() {
const { activeAccountInfo } = useAccountStore();
const { hasBitcoinAddresses } = useAccountStore();
const { addressInfos, accountBalance } = useAddressStore();
const { accountBalance: btcAccountBalance } = useBtcAddressStore();
const { currency: fiatCurrency, exchangeRates } = useFiatStore();
const { btcUnit, canUseSwaps } = useSettingsStore();
const hasBitcoinAddresses = computed(() => (activeAccountInfo.value || false)
&& (activeAccountInfo.value.btcAddresses || false)
&& activeAccountInfo.value.btcAddresses.external.length > 0);
const nimExchangeRate = computed(() => exchangeRates.value[CryptoCurrency.NIM]?.[fiatCurrency.value]);
const btcExchangeRate = computed(() => exchangeRates.value[CryptoCurrency.BTC]?.[fiatCurrency.value]);
Expand Down
7 changes: 2 additions & 5 deletions src/components/BtcTransactionList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,8 @@ export default defineComponent({
const scrollerBuffer = 300;
// Height of items in pixel
const { width: windowWidth } = useWindowSize();
const itemSize = computed(() => windowWidth.value > 700 // Full mobile breakpoint
? 72
: 68, // 64px + 4px margin between items
);
const { isMobile } = useWindowSize();
const itemSize = computed(() => isMobile.value ? 68 : 72); // mobile: 64px + 4px margin between items
// Get all transactions for the active addresses
const txsForActiveAddress = computed(() => Object.values(btcTransactions$.transactions)
Expand Down
6 changes: 1 addition & 5 deletions src/components/IdenticonStack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default defineComponent({
},
},
setup() {
const { activeAccountInfo, activeCurrency } = useAccountStore();
const { activeCurrency, hasBitcoinAddresses } = useAccountStore();
const { addressInfos, activeAddressInfo } = useAddressStore();
const backgroundAddresses = computed(() =>
Expand All @@ -50,10 +50,6 @@ export default defineComponent({
.map((addressInfo) => addressInfo.address),
);
const hasBitcoinAddresses = computed(() => (activeAccountInfo.value || false)
&& (activeAccountInfo.value.btcAddresses || false)
&& activeAccountInfo.value.btcAddresses.external.length > 0);
return {
backgroundAddresses,
hasBitcoinAddresses,
Expand Down
39 changes: 33 additions & 6 deletions src/components/MobileActionBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@
<script lang="ts">
import { defineComponent, computed } from '@vue/composition-api';
import { ArrowRightSmallIcon, ScanQrCodeIcon } from '@nimiq/vue-components';
import { useAddressStore } from '../stores/Address';
import { AddressType, useAddressStore } from '../stores/Address';
import { useAccountStore } from '../stores/Account';
import { CryptoCurrency } from '../lib/Constants';
import { useBtcAddressStore } from '../stores/BtcAddress';
import { useWindowSize } from '../composables/useWindowSize';
import { ColumnType, useActiveMobileColumn } from '../composables/useActiveMobileColumn';
export default defineComponent({
setup(props, context) {
const { activeAddressInfo } = useAddressStore();
const { activeCurrency } = useAccountStore();
const { activeAddressInfo, addressInfos } = useAddressStore();
const { activeCurrency, activeAccountInfo, hasBitcoinAddresses } = useAccountStore();
const { accountBalance } = useBtcAddressStore();
const { isMobile } = useWindowSize();
const { activeMobileColumn } = useActiveMobileColumn();
function nimOrBtc<T>(nim: T, btc: T): T {
switch (activeCurrency.value) {
Expand All @@ -37,15 +41,37 @@ export default defineComponent({
}
}
const hasMultipleReceivableAddresses = computed(() => (
addressInfos.value.filter(({ type }) => type === AddressType.BASIC).length > 1));
function receive() {
context.root.$router.push(nimOrBtc<string>('/receive', '/btc-receive'));
if (isMobile.value
&& activeMobileColumn.value !== ColumnType.ADDRESS
&& (hasMultipleReceivableAddresses.value || hasBitcoinAddresses.value)
) {
// redirect to the address selector
context.root.$router.push('/receive');
} else {
context.root.$router.push(nimOrBtc('/receive/nim', '/receive/btc'));
}
}
const hasMultipleSendableAddresses = computed(() =>
activeAccountInfo.value && activeAccountInfo.value.addresses.length > 1);
function send() {
context.root.$router.push(nimOrBtc<string>('/send', '/btc-send'));
if (isMobile.value
&& activeMobileColumn.value !== ColumnType.ADDRESS
&& (hasMultipleSendableAddresses.value || hasBitcoinAddresses.value)
) {
// redirect to the address selector
context.root.$router.push('/send');
} else {
context.root.$router.push(nimOrBtc('/send/nim', '/send/btc'));
}
}
const sendDisabled = computed(() => nimOrBtc(
const sendDisabled = computed(() => context.root.$route.path !== '/' && nimOrBtc(
!activeAddressInfo.value || !activeAddressInfo.value.balance,
!accountBalance.value,
));
Expand All @@ -68,6 +94,7 @@ export default defineComponent({
justify-content: space-between;
align-items: center;
padding: 2rem;
padding-bottom: max(2rem, env(safe-area-inset-bottom));
background: white;
display: none;
Expand Down
7 changes: 2 additions & 5 deletions src/components/TransactionList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,8 @@ export default defineComponent({
const scrollerBuffer = 300;
// Height of items in pixel
const { width: windowWidth } = useWindowSize();
const itemSize = computed(() => windowWidth.value > 700 // Full mobile breakpoint
? 72
: 68, // 64px + 4px margin between items
);
const { isMobile } = useWindowSize();
const itemSize = computed(() => isMobile.value ? 68 : 72); // mobile: 64px + 4px margin between items
// Get all transactions for the active address
const txsForActiveAddress = computed(() => Object.values(transactions$.transactions)
Expand Down
22 changes: 12 additions & 10 deletions src/components/layouts/AccountOverview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,13 @@ import { useSettingsStore } from '../../stores/Settings';
export default defineComponent({
name: 'account-overview',
setup(props, context) {
const { activeAccountInfo, activeAccountId, setActiveCurrency, activeCurrency } = useAccountStore();
const {
activeAccountInfo,
activeAccountId,
setActiveCurrency,
activeCurrency,
hasBitcoinAddresses,
} = useAccountStore();
const { accountBalance: btcAccountBalance } = useBtcAddressStore();
const isLegacyAccount = computed(() => (activeAccountInfo.value || false)
Expand All @@ -149,37 +155,33 @@ export default defineComponent({
const canHaveMultipleAddresses = computed(() => (activeAccountInfo.value || false)
&& activeAccountInfo.value.type !== AccountType.LEGACY);
const hasBitcoinAddresses = computed(() => (activeAccountInfo.value || false)
&& (activeAccountInfo.value.btcAddresses || false)
&& activeAccountInfo.value.btcAddresses.external.length > 0);
const { width } = useWindowSize();
const { isMobile, isTablet } = useWindowSize();
function onAddressSelected() {
setActiveCurrency(CryptoCurrency.NIM);
if (width.value <= 700) { // Full mobile breakpoint
if (isMobile.value) {
context.root.$router.push('/transactions');
}
}
function selectBitcoin() {
setActiveCurrency(CryptoCurrency.BTC);
if (width.value <= 700) { // Full mobile breakpoint
if (isMobile.value) {
context.root.$router.push('/transactions');
}
}
const showFullLegacyAccountNotice = computed(() =>
isLegacyAccount.value
&& activeAccountInfo.value!.addresses.length === 1
&& width.value > 960); // Tablet breakpoint
&& !isTablet.value);
const showModalLegacyAccountNotice = ref(false);
function determineIfShowModalLegacyAccountNotice() {
showModalLegacyAccountNotice.value = isLegacyAccount.value && width.value <= 960; // Tablet breakpoint
showModalLegacyAccountNotice.value = isLegacyAccount.value && isTablet.value;
}
function determineModalToShow() {
Expand Down
Loading

0 comments on commit 492d602

Please sign in to comment.