Create subscription management view

This commit is contained in:
silverpill 2022-05-18 18:29:33 +00:00
parent 35496116cd
commit be63806e9d
3 changed files with 203 additions and 104 deletions

View file

@ -13,6 +13,7 @@ import PostOverlay from "@/views/PostOverlay.vue"
import PublicTimeline from "@/views/PublicTimeline.vue"
import TagTimeline from "@/views/TagTimeline.vue"
import SearchResultList from "@/views/SearchResultList.vue"
import SubscriptionView from "@/views/Subscription.vue"
import { useCurrentUser } from "@/store/user"
@ -99,6 +100,12 @@ const routes: Array<RouteRecordRaw> = [
component: ProfileView,
meta: { onlyAuthenticated: true },
},
{
path: "/profile/:profileId/subscription",
name: "profile-subscription",
component: SubscriptionView,
meta: { },
},
{
path: "/profile-directory",
name: "profile-directory",

View file

@ -49,29 +49,21 @@
Verify ethereum address
</button>
</li>
<li v-if="canConnectWallet()">
<button
title="Connect wallet"
@click="hideProfileMenu(); connectWallet()"
>
Connect wallet
</button>
</li>
<li v-if="canConfigureSubscription()">
<button
<router-link
title="Set up subscription"
@click="hideProfileMenu(); configureSubscription()"
:to="{ name: 'profile-subscription', params: { profileId: profile.id }}"
>
Set up subscription
</button>
</router-link>
</li>
<li v-if="canSubscribe()">
<button
<router-link
title="Pay for subscription"
@click="hideProfileMenu(); makeSubscriptionPayment()"
:to="{ name: 'profile-subscription', params: { profileId: profile.id }}"
>
Pay for subscription
</button>
</router-link>
</li>
<li v-if="canHideReposts()">
<button @click="follow(false, undefined)">Hide reposts</button>
@ -175,12 +167,6 @@ import {
getFollowers,
getFollowing,
} from "@/api/relationships"
import {
getSubscriptionAuthorization,
configureSubscription,
isSubscriptionConfigured,
makeSubscriptionPayment,
} from "@/api/subscriptions"
import {
createIdentityProof,
getIdentityClaim,
@ -405,94 +391,12 @@ export default class ProfileView extends Vue {
this.profile.identity_proofs = profile.identity_proofs
}
canConnectWallet(): boolean {
return Boolean(this.store.instance?.blockchain_contract_address) && !this.walletConnected
}
async connectWallet() {
// Part of subscription UI
const signer = await getWallet()
if (!signer) {
return
}
this.walletConnected = true
this.checkSubscriptionConfigured()
}
canConfigureSubscription(): boolean {
// If wallet is not connected, subscriptionConfigured is set to null
return this.isCurrentUser() && this.subscriptionConfigured === false
}
private async checkSubscriptionConfigured() {
const { instance } = this.store
if (
!this.profile ||
!this.profile.wallet_address ||
!instance ||
!instance.blockchain_contract_address
) {
return
}
const signer = await getWallet()
if (!signer) {
return
}
this.subscriptionConfigured = await isSubscriptionConfigured(
instance.blockchain_contract_address,
signer,
this.profile.wallet_address,
)
}
async configureSubscription() {
const { currentUser, instance } = this.store
if (
!currentUser ||
!instance ||
!instance.blockchain_contract_address
) {
return
}
// Subscription configuration tx can be send from any address
const signer = await getWallet()
if (!signer) {
return
}
const authToken = this.store.ensureAuthToken()
const signature = await getSubscriptionAuthorization(authToken)
await configureSubscription(
instance.blockchain_contract_address,
signer,
currentUser.wallet_address,
signature,
)
this.subscriptionConfigured = true
return Boolean(this.store.instance?.blockchain_contract_address) && Boolean(this.profile?.wallet_address) && this.isCurrentUser()
}
canSubscribe(): boolean {
return this.subscriptionConfigured === true && !this.isCurrentUser()
}
async makeSubscriptionPayment() {
const { instance } = this.store
if (
!this.profile ||
!this.profile.wallet_address ||
!instance ||
!instance.blockchain_contract_address
) {
return
}
const signer = await getWallet()
if (!signer) {
return
}
await makeSubscriptionPayment(
instance.blockchain_contract_address,
signer,
this.profile.wallet_address,
)
return Boolean(this.store.instance?.blockchain_contract_address) && Boolean(this.profile?.wallet_address) && !this.isCurrentUser()
}
async loadNextPage(maxId: string) {

188
src/views/Subscription.vue Normal file
View file

@ -0,0 +1,188 @@
<template>
<div id="main" v-if="profile">
<div class="content subscription">
<h1>
Subscription: @{{ getActorAddress(profile) }}
</h1>
<div class="connect-wallet" v-if="canConnectWallet()">
<button class="btn" @click="connectWallet()">Connect wallet</button>
</div>
<div class="setup" v-if="canConfigureSubscription()">
<template v-if="subscriptionConfigured">
Subscription is configured.
</template>
<button v-else class="btn" @click="onConfigureSubscription()">
Set up subscription
</button>
</div>
<div class="payment" v-if="canSubscribe()">
<template v-if="!subscriptionConfigured">
Subscription is not available.
</template>
<button v-else class="btn" @click="onMakeSubscriptionPayment()">
Pay for subscription
</button>
</div>
</div>
<sidebar></sidebar>
</div>
</template>
<script setup lang="ts">
/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
import { ref, onMounted } from "vue"
import { useRoute } from "vue-router"
import { getProfile, Profile } from "@/api/users"
import {
getSubscriptionAuthorization,
configureSubscription,
isSubscriptionConfigured,
makeSubscriptionPayment,
} from "@/api/subscriptions"
import Sidebar from "@/components/Sidebar.vue"
import { useInstanceInfo } from "@/store/instance"
import { useCurrentUser } from "@/store/user"
import { getWallet } from "@/utils/ethereum"
const route = useRoute()
const { currentUser, ensureAuthToken } = $(useCurrentUser())
const { instance, getActorAddress } = $(useInstanceInfo())
let profile = $ref<Profile | null>(null)
let walletConnected = $ref(false)
let subscriptionConfigured = $ref<boolean | null>(null)
onMounted(async () => {
const { authToken } = useCurrentUser()
profile = await getProfile(
authToken,
route.params.profileId,
)
})
function isCurrentUser(): boolean {
if (!currentUser || !profile) {
return false
}
return currentUser.id === profile.id
}
function canConnectWallet(): boolean {
return (
Boolean(instance?.blockchain_contract_address) &&
Boolean(profile?.wallet_address) &&
!walletConnected
)
}
async function connectWallet() {
const signer = await getWallet()
if (!signer) {
return
}
walletConnected = true
checkSubscriptionConfigured()
}
async function checkSubscriptionConfigured() {
if (
!profile ||
!profile.wallet_address ||
!instance ||
!instance.blockchain_contract_address
) {
return
}
const signer = await getWallet()
if (!signer) {
return
}
subscriptionConfigured = await isSubscriptionConfigured(
instance.blockchain_contract_address,
signer,
profile.wallet_address,
)
}
function canConfigureSubscription(): boolean {
// If wallet is not connected, subscriptionConfigured is set to null
return isCurrentUser() && subscriptionConfigured !== null
}
async function onConfigureSubscription() {
if (
!currentUser ||
!isCurrentUser() ||
!instance ||
!instance.blockchain_contract_address
) {
return
}
// Subscription configuration tx can be send from any address
const signer = await getWallet()
if (!signer) {
return
}
const authToken = ensureAuthToken()
const signature = await getSubscriptionAuthorization(authToken)
await configureSubscription(
instance.blockchain_contract_address,
signer,
currentUser.wallet_address,
signature,
)
subscriptionConfigured = true
}
function canSubscribe(): boolean {
return !isCurrentUser() && subscriptionConfigured !== null
}
async function onMakeSubscriptionPayment() {
if (
!profile ||
!profile.wallet_address ||
!instance ||
!instance.blockchain_contract_address
) {
return
}
const signer = await getWallet()
if (!signer) {
return
}
await makeSubscriptionPayment(
instance.blockchain_contract_address,
signer,
profile.wallet_address,
)
}
</script>
<style scoped lang="scss">
@import "../styles/layout";
@import "../styles/mixins";
@import "../styles/theme";
.subscription {
@include block-btn;
background-color: $block-background-color;
border-radius: $block-border-radius;
margin-bottom: $block-outer-padding;
padding: $block-inner-padding;
h1 {
font-size: 20px;
text-align: center;
}
}
.connect-wallet,
.setup,
.payment {
display: flex;
justify-content: center;
}
</style>