Compare commits

..

No commits in common. '34b767d631f587c261a2c7cddb2345c2a09d4476' and '52ad71712e3435850242f3f48fe695a02cece3df' have entirely different histories.

  1. 3
      src/api.ts
  2. 9
      src/assets/main.css
  3. 50
      src/components/DomainBar.vue
  4. 24
      src/components/DomainTable.vue
  5. 122
      src/components/SiteSettings.vue
  6. 6
      src/components/TemplatesList.vue
  7. 17
      src/components/Tooltip.vue
  8. 15
      src/components/ZonePricing.vue
  9. 63
      src/components/ZoneTable.vue
  10. 114
      src/result.ts
  11. 2
      src/router/index.ts
  12. 76
      src/views/Explore.vue
  13. 20
      src/views/Find.vue

3
src/api.ts

@ -12,19 +12,16 @@ export class Api {
public readonly tonscan_url: string; public readonly tonscan_url: string;
public agorata_adnl: string = public agorata_adnl: string =
"ed4f2afebb5e49dda9684a474c5771141be1f7d85a2fa39f1823844dd476c52d"; "ed4f2afebb5e49dda9684a474c5771141be1f7d85a2fa39f1823844dd476c52d";
public readonly tonviewer_url: string;
constructor() { constructor() {
if (process.env.NODE_ENV === "development" && false) { if (process.env.NODE_ENV === "development" && false) {
this.api_url = "http://localhost:5170/"; this.api_url = "http://localhost:5170/";
this.ton_api_url = "https://testnet.tonapi.io/v2/"; this.ton_api_url = "https://testnet.tonapi.io/v2/";
this.tonscan_url = "https://testnet.tonscan.org/"; this.tonscan_url = "https://testnet.tonscan.org/";
this.tonviewer_url = "https://testnet.tonviewer.com/";
} else { } else {
this.api_url = "https://agorata.io/api/"; this.api_url = "https://agorata.io/api/";
this.ton_api_url = "https://tonapi.io/v2/"; this.ton_api_url = "https://tonapi.io/v2/";
this.tonscan_url = "https://tonscan.org/"; this.tonscan_url = "https://tonscan.org/";
this.tonviewer_url = "https://testnet.tonviewer.com/";
} }
} }
} }

9
src/assets/main.css

@ -1,4 +1,4 @@
@import "./base.css"; @import './base.css';
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@ -126,7 +126,7 @@ a,
} }
.mono { .mono {
font-family: "Inconsolata", monospace; font-family: 'Inconsolata', monospace;
} }
:root { :root {
@ -142,7 +142,7 @@ a,
.popper { .popper {
font-size: 0.8rem; font-size: 0.8rem;
font-family: "Inconsolata", monospace; font-family: 'Inconsolata', monospace;
} }
.mobile-scale { .mobile-scale {
@ -160,6 +160,7 @@ a,
color: #363e5e; color: #363e5e;
border-radius: 0.5rem; border-radius: 0.5rem;
padding: 0.2rem 0.8rem; padding: 0.2rem 0.8rem;
margin-left: 0.9rem;
cursor: pointer; cursor: pointer;
} }
@ -176,7 +177,7 @@ a,
} }
.b.back { .b.back {
font-family: "Inconsolata", monospace; font-family: 'Inconsolata', monospace;
font-size: 1.5rem; font-size: 1.5rem;
padding: 0.8rem; padding: 0.8rem;
} }

50
src/components/DomainBar.vue

@ -1,18 +1,8 @@
<template> <template>
<div class="title">Find the domain of interest in the zone:</div> <div :class="{'domain-bar': true, 'center': !has_button}">
<div :class="{ 'domain-bar': true, center: !has_button }">
<div style="display: flex" class="prompt-cont"> <div style="display: flex" class="prompt-cont">
<contenteditable <contenteditable :contenteditable="editable" tag="div" class="prompt" :no-nl="true" v-model="val" :no-html="true"
:contenteditable="editable" ref="domain_field" @returned="search()" spellcheck="false"></contenteditable>
tag="div"
class="prompt"
:no-nl="true"
v-model="val"
:no-html="true"
ref="domain_field"
@returned="search()"
spellcheck="false"
></contenteditable>
<div class="post-prompt">{{ zone }}</div> <div class="post-prompt">{{ zone }}</div>
</div> </div>
<div class="search" v-if="has_button" @click="search()">Search</div> <div class="search" v-if="has_button" @click="search()">Search</div>
@ -20,7 +10,7 @@
</template> </template>
<script> <script>
import contenteditable from "vue-contenteditable"; import contenteditable from 'vue-contenteditable';
export default { export default {
name: "DomainBar", name: "DomainBar",
@ -28,25 +18,25 @@ export default {
props: { props: {
zone: { zone: {
type: String, type: String,
default: ".*", default: ".*"
}, },
has_button: { has_button: {
type: Boolean, type: Boolean,
default: true, default: true
}, },
value: { value: {
type: String, type: String,
default: "example", default: "example"
}, },
editable: { editable: {
type: Boolean, type: Boolean,
default: true, default: true
}, }
}, },
data() { data() {
return { return {
val: this.value, val: this.value
}; }
}, },
mounted() { mounted() {
this.$refs["domain_field"].$el.focus(); this.$refs["domain_field"].$el.focus();
@ -54,18 +44,18 @@ export default {
methods: { methods: {
search() { search() {
this.$emit("search", this.val); this.$emit("search", this.val);
}, }
}, },
watch: { watch: {
value: function (val) { value: function (val) {
val = val.replace("\n", ""); val = val.replace('\n', '');
this.val = val; this.val = val;
}, },
val: function (val) { val: function (val) {
this.$emit("input_d", val); this.$emit("input_d", val);
}, }
}, }
}; }
</script> </script>
<style scoped> <style scoped>
@ -97,7 +87,9 @@ export default {
width: 90vw; width: 90vw;
/* allow multiple rows with 0.5 spacing */ /* allow multiple rows with 0.5 spacing */
flex-wrap: wrap; flex-wrap: wrap;
} }
} }
.prompt { .prompt {
@ -139,10 +131,6 @@ export default {
} }
.post-prompt { .post-prompt {
font-family: "Inconsolata", monospace; font-family: 'Inconsolata', monospace;
}
.title {
margin-bottom: 6px;
} }
</style> </style>

24
src/components/DomainTable.vue

@ -85,26 +85,11 @@ onMounted(async () => {
zonesAddresses.value = zones.map(({ address }) => address?.toLowerCase()); zonesAddresses.value = zones.map(({ address }) => address?.toLowerCase());
if (address.value) { if (address.value) {
const [ const { data } = await axios.get<{ nft_items: CollectionItem[] }>(
resultNfts = { data: { nft_items: [] } },
resultTonNfts = { data: { nft_items: [] } },
] = await Promise.all([
axios.get<{ nft_items: CollectionItem[] }>(
`${config.ton_api_url}accounts/${address.value}/nfts` `${config.ton_api_url}accounts/${address.value}/nfts`
), );
axios.get<{ nft_items: CollectionItem[] }>(
`${config.ton_api_url}accounts/${address.value}/nfts`,
{
params: {
collection: "EQC3dNlesgVD8YbAazcauIrXBPfiVhMMr5YYk2in0Mtsz0Bz",
},
}
),
]);
items.value = [ items.value = data.nft_items
...resultTonNfts.data.nft_items,
...resultNfts.data.nft_items
.map((item) => ({ .map((item) => ({
...item, ...item,
formattedCollectionAddress: item.collection?.address formattedCollectionAddress: item.collection?.address
@ -113,8 +98,7 @@ onMounted(async () => {
})) }))
.filter(({ formattedCollectionAddress }) => .filter(({ formattedCollectionAddress }) =>
zonesAddresses.value.includes(formattedCollectionAddress) zonesAddresses.value.includes(formattedCollectionAddress)
), );
];
} }
}); });
</script> </script>

122
src/components/SiteSettings.vue

@ -1,53 +1,24 @@
<template> <template>
<div class="center"> <div class="center">
<div>Host domain by:</div>
<div class="constr-switcher"> <div class="constr-switcher">
<div <div
@click="constructor_site = true" @click="constructor_site = true"
:class="{ inactive: !constructor_site, 'constr-switch': true }" :class="{ inactive: !constructor_site, 'constr-switch': true }"
> >
Selected template By template
</div> </div>
<div <div
@click="constructor_site = false" @click="constructor_site = false"
:class="{ inactive: constructor_site, 'constr-switch': true }" :class="{ inactive: constructor_site, 'constr-switch': true }"
> >
Custom server Host your own
</div> </div>
</div> </div>
<div class="adnl-label" v-if="!constructor_site">
You can use a custom server with an address in ADNL, TON's networking
layer
<Tooltip position="top" :width="300" class="adnl-tooltip">
<template v-slot:content>
The easiest way to set up an ADNL server is to use
<a href="https://github.com/tonwhales/ton-proxy" target="_blank"
>TON Proxy</a
>
</template>
<svg
width="24px"
height="24px"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6 how-to-get"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z"
/>
</svg>
</Tooltip>
</div>
<div id="site_input" class="rec-field" v-if="!constructor_site"> <div id="site_input" class="rec-field" v-if="!constructor_site">
<div class="adnl-panel"> <div style="display: flex; width: 100%">
<p class="label">Site:</p> <p style="width: 9rem">Site:</p>
<contenteditable <contenteditable
class="record-inp site-record-field adnl-input" class="record-inp site-record-field"
tag="div" tag="div"
:no-hl="true" :no-hl="true"
:no-html="true" :no-html="true"
@ -56,13 +27,14 @@
></contenteditable> ></contenteditable>
<div <div
:class="{ :class="{
'record-submit': true,
get_b: true, get_b: true,
inactive: inactiveSave, inactive: inactiveSave,
signing: signingSite, signing: signingSite,
}" }"
@click="$emit('save')" @click="$emit('save')"
> >
<template v-if="!signingSite">Save and host</template> <template v-if="!signingSite">Save</template>
<template v-else> <template v-else>
<Socket <Socket
secondary-color="#a7aab3" secondary-color="#a7aab3"
@ -78,12 +50,7 @@
<div v-else class="constructor-form"> <div v-else class="constructor-form">
<Switcher <Switcher
:items="templates" :items="templates"
@change=" @change="(item) => (activeTemplateName = item.name)"
(item) => {
activeTemplateName = item.name;
selectTemplate(item);
}
"
:active-name="activeTemplateName" :active-name="activeTemplateName"
> >
<template v-slot:suffix> <template v-slot:suffix>
@ -96,20 +63,14 @@
</template> </template>
</Switcher> </Switcher>
<TemplatesList <TemplatesList
:site-changed="siteChanged"
:templates="templates" :templates="templates"
:active-template-name="activeTemplateName" :active-template-name="activeTemplateName"
:site-changed="siteChanged"
:constructor-changed="constructorChanged" :constructor-changed="constructorChanged"
:site_rec_init="site_rec_init" :site_rec_init="site_rec_init"
:signing-site="signingSite" :signing-site="signingSite"
@change=" @change="site_rec = $event; $emit('change', site_rec_patched)"
site_rec = $event; @change-constructor="constructor_params = $event; $emit('change-constructor', constructor_params)"
$emit('change', site_rec_patched);
"
@change-constructor="
constructor_params = $event;
$emit('change-constructor', constructor_params);
"
@save="$emit('save', $event)" @save="$emit('save', $event)"
@save-constructor="$emit('save-constructor', $event)" @save-constructor="$emit('save-constructor', $event)"
/> />
@ -125,11 +86,10 @@ import { default_links, SiteConstructorParams } from "../result";
import { link_types, link_icons } from "../result"; import { link_types, link_icons } from "../result";
import TemplatesList from "./TemplatesList.vue"; import TemplatesList from "./TemplatesList.vue";
import Switcher from "./Switcher.vue"; import Switcher from "./Switcher.vue";
import Tooltip from "./Tooltip.vue";
export default { export default {
name: "SiteSettings", name: "SiteSettings",
components: { Socket, contenteditable, TemplatesList, Switcher, Tooltip }, components: { Socket, contenteditable, TemplatesList, Switcher },
props: { props: {
site_rec_init: { site_rec_init: {
default: null, default: null,
@ -146,9 +106,6 @@ export default {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
templateId: {
type: String,
},
}, },
data() { data() {
let site_rec = this.site_rec_init; let site_rec = this.site_rec_init;
@ -195,9 +152,6 @@ export default {
}, },
deep: true, deep: true,
}, },
templateId() {
if (this.templateId) this.activeTemplateName = this.templateId;
},
}, },
computed: { computed: {
site_rec_patched() { site_rec_patched() {
@ -207,11 +161,10 @@ export default {
return this.site_rec; return this.site_rec;
} }
}, },
templateId() {
return this.templateId;
},
inactiveSave() { inactiveSave() {
return !this.siteChanged && this.site_rec !== null; return (
!this.siteChanged && this.site_rec !== null
);
}, },
link_types() { link_types() {
// return the types from link_types that are not in the constructor_params.contacts // return the types from link_types that are not in the constructor_params.contacts
@ -244,9 +197,6 @@ export default {
name: `Template #${i + 1}`, name: `Template #${i + 1}`,
})); }));
}, },
selectTemplate(template) {
this.$emit("select-template", template);
},
}, },
mounted() { mounted() {
this.setTemplates(); this.setTemplates();
@ -261,9 +211,12 @@ export default {
<style scoped> <style scoped>
.record-inp { .record-inp {
padding: 0.3rem; padding: 0.3rem;
margin-left: 0.5rem;
border-radius: 0.3rem; border-radius: 0.3rem;
background-color: #4e5a88; background-color: #4e5a88;
color: white; color: white;
min-width: 50vw;
width: 100%;
} }
.rec-field:not(:last-child) { .rec-field:not(:last-child) {
@ -285,6 +238,10 @@ export default {
font-size: 1.4rem; font-size: 1.4rem;
} }
.get_b {
max-width: 8rem;
}
.constructor-form > div > div:not(:last-child) { .constructor-form > div > div:not(:last-child) {
margin-bottom: 1rem; margin-bottom: 1rem;
} }
@ -306,8 +263,8 @@ export default {
border-radius: 0.7rem; border-radius: 0.7rem;
background-color: #cdcee8; background-color: #cdcee8;
color: #282e46; color: #282e46;
width: 13rem;
cursor: default; cursor: default;
width: 250px;
} }
.constr-switch:not(:last-child) { .constr-switch:not(:last-child) {
@ -362,37 +319,4 @@ export default {
margin-top: 1rem; margin-top: 1rem;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.how-to-get {
cursor: pointer;
}
.adnl-panel {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 10px;
& .label {
display: grid;
justify-content: end;
}
}
.adnl-label {
display: grid;
grid-auto-flow: column;
align-items: center;
gap: 6px;
margin-bottom: 6px;
}
.adnl-tooltip {
display: grid;
align-content: center;
}
.adnl-input {
width: 826px;
}
</style> </style>

6
src/components/TemplatesList.vue

@ -65,7 +65,7 @@
}" }"
@click="$emit('save-constructor')" @click="$emit('save-constructor')"
> >
<template v-if="!signingSite">Save and host</template> <template v-if="!signingSite">Save</template>
<template v-else> <template v-else>
<Socket <Socket
secondary-color="#a7aab3" secondary-color="#a7aab3"
@ -219,6 +219,10 @@ export default {
font-size: 1.4rem; font-size: 1.4rem;
} }
.get_b {
max-width: 8rem;
}
.constructor-form > div > div > div:not(:last-child) { .constructor-form > div > div > div:not(:last-child) {
margin-bottom: 1rem; margin-bottom: 1rem;
} }

17
src/components/Tooltip.vue

@ -5,12 +5,7 @@
class="tooltip-container" class="tooltip-container"
> >
<slot /> <slot />
<div <div v-if="showTooltip" class="tooltip">
v-if="showTooltip"
:class="{ tooltip: true, top: position === 'top' }"
:style="width ? `width: ${width}px` : ''"
>
<slot name="content" />
{{ text }} {{ text }}
</div> </div>
</div> </div>
@ -26,12 +21,6 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
position: {
type: String,
},
width: {
type: Number,
},
}, },
setup(props) { setup(props) {
const showTooltip = ref(false); const showTooltip = ref(false);
@ -70,9 +59,5 @@ export default {
color: #fff; color: #fff;
padding: 0.5rem; padding: 0.5rem;
border-radius: 0.25rem; border-radius: 0.25rem;
&.top {
transform: translate(-50%, calc(-100% - 24px));
}
} }
</style> </style>

15
src/components/ZonePricing.vue

@ -46,22 +46,21 @@
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>{{ "*".repeat(zone.length_2) + "." + zone.zone }}</td> <td>{{ "*".repeat(zone.length_1) + "." + zone.zone }}</td>
<td v-if="zone.canAuction()"> <td v-if="zone.canAuction()">
<TonButton>{{ zone.price_auction_2 }}</TonButton> <TonButton>{{ zone.price_auction_1 }}</TonButton>
</td> </td>
<td v-if="zone.canBuy()"> <td v-if="zone.canBuy()">
<TonButton>{{ zone.price_buy_2 }}</TonButton> <TonButton>{{ zone.price_buy_1 }}</TonButton>
<small style="display: block">to</small>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>{{ "*".repeat(zone.length_1) + "." + zone.zone }}</td> <td>{{ "*".repeat(zone.length_2) + "." + zone.zone }}</td>
<td v-if="zone.canAuction()"> <td v-if="zone.canAuction()">
<TonButton>{{ zone.price_auction_1 }}</TonButton> <TonButton>{{ zone.price_auction_2 }}</TonButton>
</td> </td>
<td v-if="zone.canBuy()"> <td v-if="zone.canBuy()">
<TonButton>{{ zone.price_buy_1 }}</TonButton> <TonButton>{{ zone.price_buy_2 }}</TonButton>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -123,6 +122,6 @@ tr > th {
} }
.get_b { .get_b {
margin-top: 3.1rem; margin-top: 2.1rem;
} }
</style> </style>

63
src/components/ZoneTable.vue

@ -1,46 +1,19 @@
<template> <template>
<div class="center" v-if="!zones.length"> <div class="center" v-if="zones === []">
<RotateSquare2 style="width: 5rem; height: 5rem; margin-top: 3rem" /> <RotateSquare2 style="width: 5rem; height: 5rem; margin-top: 3rem;"/>
</div> </div>
<div style="overflow-x: auto; max-width: 98vw" v-else> <div style="overflow-x: auto; max-width: 98vw;" v-else>
<table class="table_outer"> <table class="table_outer">
<thead class="table_header"> <thead class="table_header">
<tr> <tr>
<th>Zone</th> <th>Domain</th>
<th> <th>Terms</th>
Prices
<Tooltip style="display: inline" text="Depends on length">
<svg
style="padding-top: 4px"
width="24px"
height="24px"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6 how-to-get"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z"
/>
</svg>
</Tooltip>
</th>
</tr> </tr>
</thead> </thead>
<tbody class="table_content"> <tbody class="table_content">
<tr v-for="zone in zones" :key="zone.zone"> <tr v-for="zone in zones" :key="zone.zone">
<td class="zone"> <td class="zone">
<router-link <router-link :to="{name: 'GetZ', params: {zone: zone.zone}}" style="color: white">
:to="{
name: 'GetZ',
params: { zone: zone.zone, domain_init: domain },
}"
style="color: white"
>
{{ zone.zone }} {{ zone.zone }}
</router-link> </router-link>
</td> </td>
@ -57,21 +30,17 @@
import {Zone} from "../zone"; import {Zone} from "../zone";
import ZonePricing from "./ZonePricing.vue"; import ZonePricing from "./ZonePricing.vue";
import RotateSquare2 from "./RotateSquare2.vue"; import RotateSquare2 from "./RotateSquare2.vue";
import Tooltip from "./Tooltip.vue";
export default { export default {
name: "ZoneTable", name: "ZoneTable",
components: { ZonePricing, RotateSquare2, Tooltip }, components: {ZonePricing, RotateSquare2},
props: { props: {
zones: { zones: {
type: Array[Zone], type: Array[Zone],
default: [], default: []
}, }
domain: {
type: String,
},
}, },
}; }
</script> </script>
<style scoped> <style scoped>
@ -105,8 +74,7 @@ thead > tr {
display: flex; display: flex;
} }
tr > :last-child { tr > :last-child { /* place it on the right */
/* place it on the right */
justify-content: flex-end; justify-content: flex-end;
text-align: center; text-align: center;
width: 100%; width: 100%;
@ -116,8 +84,7 @@ tr > th:first-child {
text-align: center; text-align: center;
} }
tr > :first-child { tr > :first-child { /* place it on the left */
/* place it on the left */
text-align: left; text-align: left;
} }
@ -131,10 +98,4 @@ tr:not(:first-child) > td {
padding: 1rem; padding: 1rem;
min-height: 10rem; min-height: 10rem;
} }
.ton-coin-icon {
margin-left: 4px;
width: 15px;
height: 15px;
}
</style> </style>

114
src/result.ts

@ -18,17 +18,7 @@ export class Result {
content_msg: Message | null = null; content_msg: Message | null = null;
nft_info?: any; nft_info?: any;
constructor( 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, content_msg: Message | null = null, nft_info?: any) {
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,
content_msg: Message | null = null,
nft_info?: any
) {
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;
@ -51,45 +41,27 @@ export class Result {
let content_msg = data.content_msg; let content_msg = data.content_msg;
let nft_info = data.nft_info; let nft_info = data.nft_info;
return new Result( return new Result(domain, buy_price, auction_price, owner, collection_required, condition_fulfilled, buy_msg, content_msg, nft_info);
domain,
buy_price,
auction_price,
owner,
collection_required,
condition_fulfilled,
buy_msg,
content_msg,
nft_info
);
} }
getRouteParams(): any { getRouteParams(): any {
return { return {
domain_init: /* domain up to . */ this.domain.split(".")[0], domain_init: /* domain up to . */ this.domain.split('.')[0],
domain: /* domain up to . */ this.domain.split(".")[0], domain: /* domain up to . */ this.domain.split('.')[0],
zone: /* domain after . */ this.domain.split(".").slice(1).join("."), zone: /* domain after . */ this.domain.split('.').slice(1).join('.')
}; }
} }
canAuction(): boolean { canAuction(): boolean {
return ( return this.auction_price !== undefined && this.auction_price !== null && this.owner === undefined;
this.auction_price !== undefined &&
this.auction_price !== null &&
this.owner === undefined
);
} }
canBuy(): boolean { canBuy(): boolean {
return ( return this.buy_price !== undefined && this.buy_price !== null && this.owner === undefined;
this.buy_price !== undefined &&
this.buy_price !== null &&
this.owner === undefined
);
} }
zone(): string { zone(): string {
return this.domain.split(".").slice(1).join("."); return this.domain.split('.').slice(1).join('.');
} }
} }
@ -98,7 +70,7 @@ export class Result {
// } // }
export async function get_search_results(query: string) { export async function get_search_results(query: string) {
return Result.fromBackend(await call_api("find/" + query)); return Result.fromBackend(await call_api('find/' + query));
/*await sleep(200); /*await sleep(200);
return [ return [
new Result(query + '.ton', 5, 3), new Result(query + '.ton', 5, 3),
@ -109,7 +81,7 @@ export async function get_search_results(query: string) {
} }
export async function get_domain_result(domain: string, _address?: string) { export async function get_domain_result(domain: string, _address?: string) {
return Result.fromBackend(await call_api("get/" + domain)); return Result.fromBackend(await call_api('get/' + domain));
/*await sleep(100); /*await sleep(100);
if (domain === 'test.ton') { if (domain === 'test.ton') {
return new Result(domain); return new Result(domain);
@ -133,26 +105,12 @@ export async function get_domain_result(domain: string, _address?: string) {
} }
export async function get_records(address: string) { export async function get_records(address: string) {
return await call_api("records/" + address); return await call_api('records/' + address);
} }
export async function get_zones() { export async function get_zones() {
let zones_back = await call_api("zones"); let zones_back = await call_api('zones');
return zones_back.map( return zones_back.map((zone: any) => new Zone(zone.zone, zone.price_buy_1, zone.price_buy_2, zone.collection_required, zone.price_auction_1, zone.price_auction_2, zone.min_length, zone.length_1, zone.length_2, zone.address));
(zone: any) =>
new Zone(
zone.zone,
zone.price_buy_1,
zone.price_buy_2,
zone.collection_required,
zone.price_auction_1,
zone.price_auction_2,
zone.min_length,
zone.length_1,
zone.length_2,
zone.address
)
);
/*await sleep(10); /*await sleep(10);
return [ return [
new Zone("example.ton", 3, 5, ex_collection()), new Zone("example.ton", 3, 5, ex_collection()),
@ -183,42 +141,24 @@ export class TonLink {
// Get the link for buying a domain // Get the link for buying a domain
export function get_ton_link(res: Result) { export function get_ton_link(res: Result) {
return new TonLink(res.zone(), "b/" + res.domain, res.buy_price!); return new TonLink(res.zone(), 'b/' + res.domain, res.buy_price!);
} }
export let link_types = ["telegram", /*'website',*/ "getgems", "email"]; export let link_types = ['telegram', /*'website',*/ 'getgems', 'email'];
export let link_icons = { export let link_icons = {'telegram': 'fab fa-telegram', 'website': 'material-icons language', 'getgems': 'fas fa-gem', 'email': 'fas fa-envelope'};
telegram: "fab fa-telegram", export let default_links = {'telegram': 'https://t.me/', 'website': 'https://', 'getgems': 'https://getgems.org/', 'email': 'example@example.org'};
website: "material-icons language",
getgems: "fas fa-gem",
email: "fas fa-envelope",
};
export let default_links = {
telegram: "https://t.me/",
website: "https://",
getgems: "https://getgems.org/",
email: "example@example.org",
};
export class SiteConstructorParams { export class SiteConstructorParams {
domain: string; domain: string;
title: string; title: string;
description: string; description: string;
contacts: Map<string, string> = new Map<string, string>(); contacts: Map<string, string> = new Map<string, string>();
template_id: string;
constructor(domain: string, title: string = '', description: string = '', contacts: Map<string, string> = new Map<string, string>()) {
constructor(
domain: string,
title: string = "",
description: string = "",
contacts: Map<string, string> = new Map<string, string>(),
template_id: string = ""
) {
this.domain = domain; this.domain = domain;
this.title = title; this.title = title;
this.description = description; this.description = description;
this.contacts = contacts; this.contacts = contacts;
this.template_id = template_id;
} }
copy(): SiteConstructorParams { copy(): SiteConstructorParams {
@ -227,12 +167,6 @@ export class SiteConstructorParams {
} }
export async function get_constr_params(domain: string) { export async function get_constr_params(domain: string) {
let res = await call_api("get-site-data/" + domain); let res = await call_api('get-site-data/' + domain);
return new SiteConstructorParams( return new SiteConstructorParams(res.domain, res.title, res.description, res.contacts);
res.domain,
res.title,
res.description,
res.contacts,
res.template_id
);
} }

2
src/router/index.ts

@ -38,7 +38,7 @@ const router = createRouter({
component: () => import("../views/TonDns.vue"), component: () => import("../views/TonDns.vue"),
}, },
{ {
path: "/get/:zone/:domain_init", path: "/get/:zone",
name: "GetZ", name: "GetZ",
component: () => import("../views/Get.vue"), component: () => import("../views/Get.vue"),
props: true, props: true,

76
src/views/Explore.vue

@ -42,13 +42,9 @@
</router-link> </router-link>
</div> </div>
<br /> <br />
<div>
You can associate your domain with your wallet<br />to receive
incoming transaction at the domain address
</div>
<div id="wallet_input" class="rec-field"> <div id="wallet_input" class="rec-field">
<div class="wallet-panel"> <div style="display: flex; width: 100%">
<p class="label">Wallet:</p> <p style="width: 9rem">Wallet:</p>
<contenteditable <contenteditable
class="record-inp wallet-record-field" class="record-inp wallet-record-field"
tag="div" tag="div"
@ -57,15 +53,6 @@
spellcheck="false" spellcheck="false"
v-model="wallet_rec" v-model="wallet_rec"
></contenteditable> ></contenteditable>
<div
:class="`use-my-wallet ${
wallet_rec === $store.getters.address ? 'disabled' : ''
}`"
:disabled="wallet_rec === $store.getters.address"
@click="useMyWallet"
>
Use my wallet
</div>
<div <div
:class="{ :class="{
'record-submit': true, 'record-submit': true,
@ -92,10 +79,8 @@
ref="site_settings" ref="site_settings"
@save="saveSite()" @save="saveSite()"
@save-constructor="saveSiteConstr()" @save-constructor="saveSiteConstr()"
@select-template="selectTemplate"
@change="site_rec = $event" @change="site_rec = $event"
@change-constructor="constructor_params = $event" @change-constructor="constructor_params = $event; constructor_params.domain = domain"
:template-id="constructor_params.template_id"
:site-changed="siteChanged" :site-changed="siteChanged"
:signing-site="signingSite" :signing-site="signingSite"
/> />
@ -131,6 +116,7 @@ import contenteditable from "vue-contenteditable";
import { call_api, call_api_post, config } from "../api"; import { call_api, call_api_post, config } from "../api";
import Socket from "../components/Socket.vue"; import Socket from "../components/Socket.vue";
import SiteSettings from "../components/SiteSettings.vue"; import SiteSettings from "../components/SiteSettings.vue";
import { mintCollection } from "@/router/routes";
export default { export default {
name: "Explore", name: "Explore",
@ -148,7 +134,7 @@ export default {
}, },
}, },
data() { data() {
const saved_constructor_params = new SiteConstructorParams( let saved_constructor_params = new SiteConstructorParams(
this.domain, this.domain,
this.domain this.domain
); );
@ -214,10 +200,7 @@ export default {
}, },
isMine() { isMine() {
console.log(this.result); console.log(this.result);
return ( return this.result.owner === this.$store.getters.address;
this.result.owner === this.$store.getters.address ||
this.result.nft_info.owner.address === this.$store.getters.address
);
}, },
walletChanged() { walletChanged() {
return this.records && this.wallet_rec !== this.records.wallet; return this.records && this.wallet_rec !== this.records.wallet;
@ -229,10 +212,7 @@ export default {
this.constructor_params !== this.saved_constructor_params; this.constructor_params !== this.saved_constructor_params;
} }
return ( return (
(this.records && (this.records && (this.site_rec !== this.records.site || constr_change)) || (!this.records && constr_change) || (this.records !== null && this.site_rec === null)
(this.site_rec !== this.records.site || constr_change)) ||
(!this.records && constr_change) ||
(this.records !== null && this.site_rec === null)
); );
}, },
settingsCompLoaded() { settingsCompLoaded() {
@ -254,7 +234,7 @@ export default {
messages: [ messages: [
{ {
amount: (0.05 * 1000000000).toString(), amount: (0.05 * 1000000000).toString(),
address: this.wallet_rec ?? this.result.nft_info.address, address: this.result.nft_info.address,
payload: message, payload: message,
}, },
], ],
@ -322,15 +302,6 @@ export default {
this.saved_constructor_params; this.saved_constructor_params;
} }
}, },
selectTemplate(template) {
this.constructor_params = {
...this.constructor_params,
template_id: template.name,
};
},
useMyWallet() {
this.wallet_rec = this.$store.getters.address;
},
}, },
watch: { watch: {
records: function (val) { records: function (val) {
@ -397,13 +368,16 @@ export default {
.record-inp { .record-inp {
padding: 0.3rem; padding: 0.3rem;
margin-left: 0.5rem;
border-radius: 0.3rem; border-radius: 0.3rem;
background-color: #4e5a88; background-color: #4e5a88;
color: white; color: white;
min-width: 50vw;
width: 100%;
} }
.rec-field:not(:last-child) { .rec-field:not(:last-child) {
margin-bottom: 4rem; margin-bottom: 1rem;
} }
.get_b.inactive { .get_b.inactive {
@ -449,30 +423,4 @@ export default {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.wallet-panel {
display: grid;
grid-template-columns: auto 1fr 183px auto;
align-items: center;
gap: 10px;
& .label {
display: grid;
justify-content: end;
}
}
.use-my-wallet {
border-radius: 0.5rem;
padding: 0.2rem 0.8rem;
cursor: pointer;
background-color: #cdcee8;
color: #282e46;
&.disabled {
cursor: not-allowed;
background-color: #6a6e95;
color: #cecddb;
}
}
</style> </style>

20
src/views/Find.vue

@ -3,7 +3,7 @@
<div class="center"> <div class="center">
<DomainBar :value="query" @search="search()" @input_d="query = $event"/> <DomainBar :value="query" @search="search()" @input_d="query = $event"/>
</div> </div>
<ZoneTable :domain="query" :zones="zones" /> <ZoneTable :zones="zones"/>
</DarkLayout> </DarkLayout>
</template> </template>
@ -17,18 +17,22 @@ export default {
name: "Find", name: "Find",
data () { data () {
return { return {
query: "example", query: 'example',
zones: [], zones: []
}; }
}, },
async mounted() { async mounted() {
this.zones = await get_zones(); this.zones = await get_zones();
}, },
methods: { methods: {
search() { search() {
this.$router.push({ name: "FindQ", params: { query: this.query } }); this.$router.push({name: 'FindQ', params: {query: this.query}});
}
}, },
}, components: {ZoneTable, DarkLayout, DomainBar}
components: { ZoneTable, DarkLayout, DomainBar }, }
};
</script> </script>
<style scoped>
</style>
Loading…
Cancel
Save