Browse Source

Checkout

vue
Lev 2 years ago
parent
commit
e1bf2368bd
  1. 31
      .idea/workspace.xml
  2. 539
      src/components/Socket.vue
  3. 10
      src/result.ts
  4. 12
      src/utils.ts
  5. 35
      src/views/Checkout.vue

31
.idea/workspace.xml

@ -1,22 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="ddb8afd5-d3ba-47b1-b6d0-227403f1abf7" name="Changes" comment="TON Connect is working"> <list default="true" id="ddb8afd5-d3ba-47b1-b6d0-227403f1abf7" name="Changes" comment="Checkout">
<change afterPath="$PROJECT_DIR$/.babelrc" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/components/Socket.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/assets/main.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/assets/main.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/DarkLayout.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/DarkLayout.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/DomainBar.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/DomainBar.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/DomainResult.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/DomainResult.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/Header.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/Header.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/LoginModal.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/LoginModal.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/WhiteLayout.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/WhiteLayout.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/main.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/result.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/result.ts" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/result.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/result.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/utils.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils.ts" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/utils.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/views/Get.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/views/Get.vue" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/views/Checkout.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/views/Checkout.vue" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -98,7 +88,7 @@
<workItem from="1672337938860" duration="148000" /> <workItem from="1672337938860" duration="148000" />
<workItem from="1672483245701" duration="3321000" /> <workItem from="1672483245701" duration="3321000" />
<workItem from="1672753446569" duration="4197000" /> <workItem from="1672753446569" duration="4197000" />
<workItem from="1672782388693" duration="19429000" /> <workItem from="1672782388693" duration="23465000" />
</task> </task>
<task id="LOCAL-00001" summary="Wrote the landing"> <task id="LOCAL-00001" summary="Wrote the landing">
<created>1670844191163</created> <created>1670844191163</created>
@ -226,7 +216,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1672850074714</updated> <updated>1672850074714</updated>
</task> </task>
<option name="localTasksCounter" value="19" /> <task id="LOCAL-00019" summary="Working on the buying process">
<created>1672868732315</created>
<option name="number" value="00019" />
<option name="presentableId" value="LOCAL-00019" />
<option name="project" value="LOCAL" />
<updated>1672868732315</updated>
</task>
<option name="localTasksCounter" value="20" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@ -262,6 +259,8 @@
<MESSAGE value="Adaptivity" /> <MESSAGE value="Adaptivity" />
<MESSAGE value="Required collections + started implementing login" /> <MESSAGE value="Required collections + started implementing login" />
<MESSAGE value="TON Connect is working" /> <MESSAGE value="TON Connect is working" />
<option name="LAST_COMMIT_MESSAGE" value="TON Connect is working" /> <MESSAGE value="Working on the buying process" />
<MESSAGE value="Checkout" />
<option name="LAST_COMMIT_MESSAGE" value="Checkout" />
</component> </component>
</project> </project>

539
src/components/Socket.vue

@ -0,0 +1,539 @@
<template>
<div v-bind:style="styles" class="spinner spinner--socker">
<div v-bind:style="innerStyles" class="spinner-inner">
<div class="gel center-gel">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c1 r1">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c2 r1">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c3 r1">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c4 r1">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c5 r1">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c6 r1">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c7 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c8 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c9 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c10 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c11 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c12 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c13 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c14 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c15 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c16 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c17 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c18 r2">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c19 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c20 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c21 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c22 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c23 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c24 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c25 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c26 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c28 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c29 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c30 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c31 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c32 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c33 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c34 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c35 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c36 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
<div class="gel c37 r3">
<div class="hex-brick h1"></div>
<div class="hex-brick h2"></div>
<div class="hex-brick h3"></div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
size: {
default: '100px'
},
color: {
default: '#ec6068' // '#834c6e'
},
secondaryColor: {
default: '#7074f4' // '#286b4b'
}
},
computed: {
innerStyles() {
let size = parseInt(this.size)
return {
transform: 'scale(' + (size / 220) + ')',
'--bg-color': this.color,
'--secondary-color': this.secondaryColor
}
},
styles() {
return {
width: this.size,
height: this.size
}
}
}
}
</script>
<style lang="scss" scoped>
.spinner {
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
* {
line-height: 0;
box-sizing: border-box;
}
}
.spinner-inner {
transform-origin: center center;
width: 200px;
height: 200px;
position: relative;
}
.hex-brick {
background: var(--bg-color);
width: 30px;
height: 17px;
position: absolute;
top: 5px;
animation-name: socket-fade;
animation-duration: 2s;
animation-iteration-count: infinite;
}
.h2 {
transform: rotate(60deg);
}
.h3 {
transform: rotate(-60deg);
}
.gel {
height: 30px;
width: 30px;
transition: all .3s;
position: absolute;
top: 50%;
left: 50%;
}
.center-gel {
margin-left: -15px;
margin-top: -15px;
animation-name: socket-pulse;
animation-duration: 2s;
animation-iteration-count: infinite;
}
.c1 {
margin-left: -47px;
margin-top: -15px;
}
.c2 {
margin-left: -31px;
margin-top: -43px;
}
.c3 {
margin-left: 1px;
margin-top: -43px;
}
.c4 {
margin-left: 17px;
margin-top: -15px;
}
.c5 {
margin-left: -31px;
margin-top: 13px;
}
.c6 {
margin-left: 1px;
margin-top: 13px;
}
.c7 {
margin-left: -63px;
margin-top: -43px;
}
.c8 {
margin-left: 33px;
margin-top: -43px;
}
.c9 {
margin-left: -15px;
margin-top: 41px;
}
.c10 {
margin-left: -63px;
margin-top: 13px;
}
.c11 {
margin-left: 33px;
margin-top: 13px;
}
.c12 {
margin-left: -15px;
margin-top: -71px;
}
.c13 {
margin-left: -47px;
margin-top: -71px;
}
.c14 {
margin-left: 17px;
margin-top: -71px;
}
.c15 {
margin-left: -47px;
margin-top: 41px;
}
.c16 {
margin-left: 17px;
margin-top: 41px;
}
.c17 {
margin-left: -79px;
margin-top: -15px;
}
.c18 {
margin-left: 49px;
margin-top: -15px;
}
.c19 {
margin-left: -63px;
margin-top: -99px;
}
.c20 {
margin-left: 33px;
margin-top: -99px;
}
.c21 {
margin-left: 1px;
margin-top: -99px;
}
.c22 {
margin-left: -31px;
margin-top: -99px;
}
.c23 {
margin-left: -63px;
margin-top: 69px;
}
.c24 {
margin-left: 33px;
margin-top: 69px;
}
.c25 {
margin-left: 1px;
margin-top: 69px;
}
.c26 {
margin-left: -31px;
margin-top: 69px;
}
.c27 {
margin-left: -79px;
margin-top: -15px;
}
.c28 {
margin-left: -95px;
margin-top: -43px;
}
.c29 {
margin-left: -95px;
margin-top: 13px;
}
.c30 {
margin-left: 49px;
margin-top: 41px;
}
.c31 {
margin-left: -79px;
margin-top: -71px;
}
.c32 {
margin-left: -111px;
margin-top: -15px;
}
.c33 {
margin-left: 65px;
margin-top: -43px;
}
.c34 {
margin-left: 65px;
margin-top: 13px;
}
.c35 {
margin-left: -79px;
margin-top: 41px;
}
.c36 {
margin-left: 49px;
margin-top: -71px;
}
.c37 {
margin-left: 81px;
margin-top: -15px;
}
.r1 {
animation-name: socket-pulse;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-delay: .2s;
}
.r2 {
animation-name: socket-pulse;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-delay: .4s;
}
.r3 {
animation-name: socket-pulse;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-delay: .6s;
}
.r1 > .hex-brick {
animation-name: socket-fade;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-delay: .2s;
}
.r2 > .hex-brick {
animation-name: socket-fade;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-delay: .4s;
}
.r3 > .hex-brick {
animation-name: socket-fade;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-delay: .6s;
}
@keyframes socket-pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(0.01);
}
100% {
transform: scale(1);
}
}
@keyframes socket-fade {
0% {
background: var(--bg-color);
}
50% {
background: var(--secondary-color);
}
100% {
background: var(--bg-color);
}
}
</style>

10
src/result.ts

@ -2,7 +2,7 @@
import {Zone} from "@/zone"; import {Zone} from "@/zone";
import {Collection} from "@/collection"; import {Collection} from "@/collection";
import {parse_zone} from "@/utils"; import {parse_zone, Message} from "@/utils";
let ex_collection = () => new Collection("example.ton", "Example collection"); let ex_collection = () => new Collection("example.ton", "Example collection");
@ -12,15 +12,17 @@ export class Result {
auction_price?: number; auction_price?: number;
owner?: string; owner?: string;
collection_required: Collection | null; collection_required: Collection | null;
condition_fullfilled: boolean | null = null; condition_fulfilled: boolean | null = null;
buy_msg: Message | null = null;
constructor(domain: string, buy_price?: number, auction_price?: number, owner?: string, collection_required: Collection | null = null, condition_fullfilled: boolean | null = null) { constructor(domain: string, buy_price?: number, auction_price?: number, owner?: string, collection_required: Collection | null = null, condition_fulfilled: boolean | null = null, buy_msg: Message | null = null) {
this.domain = domain; this.domain = domain;
this.buy_price = buy_price; this.buy_price = buy_price;
this.auction_price = auction_price; this.auction_price = auction_price;
this.owner = owner; this.owner = owner;
this.collection_required = collection_required; this.collection_required = collection_required;
this.condition_fullfilled = condition_fullfilled; this.condition_fulfilled = condition_fulfilled;
this.buy_msg = buy_msg;
} }
getRouteParams(): any { getRouteParams(): any {

12
src/utils.ts

@ -1,3 +1,15 @@
export class Message {
address: string;
amount: string;
payload: string;
constructor(address: string, amount: string, payload: string) {
this.address = address;
this.amount = amount;
this.payload = payload;
}
}
export function qr_options(url: string, imageSize: number = 0.4, imageMargin: number = 3, margin: number = 10): any { export function qr_options(url: string, imageSize: number = 0.4, imageMargin: number = 3, margin: number = 10): any {
return { return {
width: 300, width: 300,

35
src/views/Checkout.vue

@ -11,12 +11,9 @@
<!-- todo: handle auction --> <!-- todo: handle auction -->
<div class="text">To buy</div> <div class="text">To buy</div>
<DomainBar :zone="'.' + zone" :value="domain" :has_button="false" :editable="false"/> <DomainBar :zone="'.' + zone" :value="domain" :has_button="false" :editable="false"/>
<div class="text">Scan this:</div> <div class="text">Confirm the transaction in your wallet</div>
<div class="qr" v-if="loaded"> <div class="center">
<div ref="qrCode"></div> <Socket/>
</div>
<div v-else class="center">
<RotateSquare2 style="width: 5rem; height: 5rem; margin-top: 5rem"/>
</div> </div>
</DarkLayout> </DarkLayout>
</template> </template>
@ -25,13 +22,13 @@
import DarkLayout from "../components/DarkLayout.vue"; import DarkLayout from "../components/DarkLayout.vue";
import DomainBar from "../components/DomainBar.vue"; import DomainBar from "../components/DomainBar.vue";
import {get_domain_result, get_ton_link} from "../result"; import {get_domain_result, get_ton_link} from "../result";
import QRCodeStyling from 'qr-code-styling';
import RotateSquare2 from "../components/RotateSquare2.vue"; import RotateSquare2 from "../components/RotateSquare2.vue";
import {qr_options} from "../utils"; import {qr_options} from "../utils";
import Socket from "../components/Socket.vue";
export default { export default {
name: "Checkout", name: "Checkout",
components: {RotateSquare2, DomainBar, DarkLayout}, components: {Socket, RotateSquare2, DomainBar, DarkLayout},
props: { props: {
domain: { domain: {
type: String, type: String,
@ -51,15 +48,25 @@ export default {
async get_result() { async get_result() {
this.result = await get_domain_result(this.domain + '.' + this.zone); this.result = await get_domain_result(this.domain + '.' + this.zone);
this.ton_link = await get_ton_link(this.result); this.ton_link = await get_ton_link(this.result);
},
async sign_transaction()
{
await this.get_result();
let d = new Date();
let validness = parseInt((d.getTime() / 100).toFixed(0)) + 3600;
const transaction = {
validUntil: validness,
messages: [
this.result.buy_msg
]
}
await this.$store.state.connector.sendTransaction(transaction);
this.$router.push({name: 'Explore', params: {domain: this.domain + '.' + this.zone}});
} }
}, },
mounted() { mounted() {
this.get_result().then( this.get_result()
() => {
this.qr_code = new QRCodeStyling(this.options)
this.qr_code.append(this.$refs["qrCode"])
}
)
}, },
computed: { computed: {
loaded() { loaded() {

Loading…
Cancel
Save