huangjinming ac8acf4814 fix
2023-01-17 19:12:34 +08:00

1057 lines
24 KiB
Vue

<template>
<div>
<top-menu class="desk-top" :current-tab="currentTab"></top-menu>
<section class="mynft">
<div class="container">
<FilterLeft
@filter-show="showFilter"
@heroSearch="heroSearch"
@handSelect="handSelect"
@jobStatus="jobStatus"
@pieceStatus="pieceStatus"
@heroLevelChange="heroLevelChange"
@heroQualityChange="heroQualityChange"
@heroDurabilityChange="heroDurabilityChange"
@weaponSearch="weaponSearch"
@weaponQualityChange="weaponQualityChange"
@weaponLevelChange="weaponLevelChange"
@weaponDurabilityChange="weaponDurabilityChange"
@handWeaponSelect="handWeaponSelect"
@chipStatus="chipStatus"
@chipSearch="chipSearch"
@handChipSelect="handChipSelect"
@chipLevelChange="chipLevelChange"
@pieceSearch="pieceSearch"
@handPieceSelect="handPieceSelect"
:nft-type="nftType"
:isType="currentTab"
:value="value"
:heroValue="heroValue"
:jobList="jobList"
:chipList="chipList"
:pieceList="pieceList"
:selectValue="selectValue"
:options="options"
:weaponOptions="weaponOptions"
:chipOptions="chipOptions"
:pieceOptions="pieceOptions"
></FilterLeft>
<div class="right-part">
<nft-type-bar
:select-idx="nftType"
:sortOptions="sortOptions"
@handSortSelect="handSortSelect"
@nft-type-changed="onNftTypeClicked"
class="left-bar"
></nft-type-bar>
<!-- <sort-select
:filters="filters"
:selected-index="nftState"
@filter-change="filterChange"
></sort-select> -->
<!-- <nft-list
:nft-datas="nftList"
v-if="nftList.length > 0"
@activate-clicked="onActivateClick"
></nft-list> -->
<search-result
@filter-show="showFilter"
:select-idx="nftType"
:nftList="nftList"
:currencyTypeList="currencyTypeList"
:isType="currentTab"
:show-sort="true"
></search-result>
<result-no
v-if="nftList.length === 0"
title="No Record."
desc=""
></result-no>
<pagination
v-if="totalPage > 10"
:total="totalPage"
:current="currentPage"
@to-page="toPage"
class="page-comp"
></pagination>
</div>
<div class="order-status" v-show="showOrderStatus">
<el-tooltip
class="item"
effect="light"
content="Transaction in progress"
placement="right"
>
<time-loader></time-loader>
</el-tooltip>
</div>
</div>
</section>
<base-footer :auto-size="true">></base-footer>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
import SearchPanel from "@/components/market/SearchPanel.vue";
import Pagination from "@/components/market/Pagination.vue";
import SearchResult from "@/components/market/SearchResult.vue";
import TopMenu from "@/components/market/TopMenu.vue";
import NftList from "@/components/market/NftList.vue";
import { getNftList } from "@/api/Mall";
import { AppModule } from "@/store/modules/app";
import BaseFooter from "@/components/layout/BaseFooter.vue";
import NftTypeBar from "@/components/market/NftTypeBar.vue";
import SortSelect from "@/components/market/SortSelect.vue";
import FilterLeft from "@/components/market/FilterLeft.vue";
import ResultNo from "@/components/market/ResultNo.vue";
import { INftData, parseNftData } from "@/types/Nft";
import TimeLoader from "@/components/main/TimeLoader.vue";
import {
preActivateNFT,
queryActivateNFTState,
queryMyNftList,
getSupportedCurrenTypes,
} from "@/api/Market";
import { createModal, ZModal } from "@/utils/modal.util";
import { debounce } from "@/utils/formatAddress";
import RewardModal from "@/components/core/RewardModal.vue";
import { ElLoadingComponent } from "element-ui/types/loading";
import { UserModule } from "@/store/modules/user";
import ChainManager from "@/chain/ChainManager";
import { CONTRACT_ADDRESS } from "@/configs/config_chain";
const MYSTERY_BOX_CACHE = "activate_nft_cache";
@Component({
components: {
TimeLoader,
ResultNo,
SortSelect,
NftTypeBar,
BaseFooter,
NftList,
FilterLeft,
SearchResult,
SearchPanel,
Pagination,
TopMenu,
},
})
export default class MyNft extends Vue {
mobileFilterShow = false;
currentTab = "mynft";
nftList = [];
debounce: any = null;
nftType = 1;
nftState = 0;
value = 7;
timer: any = null;
heroValue = "";
selectValue = "all";
showOrderStatus = false;
private filters = ["All Items", "Normal", "Selling", "Renting"];
private options = [
{
value: null,
label: "All",
},
{
value: "Hill",
label: "Hill",
},
{
value: "Yamato",
label: "Yamato",
},
{
value: "Highest",
label: "Highest",
},
{
value: "Aoi",
label: "Aoi",
},
{
value: "Astral",
label: "Astral",
},
{
value: "Miffy",
label: "Miffy",
},
{
value: "Canoe",
label: "Canoe",
},
{
value: "Mariana",
label: "Mariana",
},
{
value: "Dragonscale",
label: "Dragonscale",
},
{
value: "Lazer",
label: "Lazer",
},
{
value: "Kurosawa",
label: "Kurosawa",
},
];
weaponOptions = [
{
value: null,
label: "All",
},
{
value: "Submachine",
label: "Submachine",
},
{
value: "Shotgun",
label: "Shotgun",
},
{
value: "Sniper",
label: "Sniper",
},
{
value: "Bazooka",
label: "Bazooka",
},
{
value: "Laser",
label: "Laser",
},
{
value: "Freeze",
label: "Freeze",
},
{
value: "Flame",
label: "Flame",
},
];
chipOptions = [
{
value: null,
label: "All",
},
{
value: "Life Source(H)",
label: "Life Source(H)",
},
{
value: "Brutal force(H)",
label: "Brutal force(H)",
},
{
value: "Tree gurad(H)",
label: "Tree gurad(H)",
},
{
value: "Sniper eye(H)",
label: "Sniper eye(H)",
},
{
value: "Sniper heart(H)",
label: "Sniper heart(H)",
},
{
value: "Limbo dodge(H)",
label: "Limbo dodge(H)",
},
{
value: "Limbo pace(H)",
label: "Limbo pace(H)",
},
{
value: "Level Green vibrant(H)",
label: "Level Green vibrant(H)",
},
{
value: "Price Brutal force(w)",
label: "Price Brutal force(w)",
},
{
value: "Sniper eye(W)",
label: "Sniper eye(W)",
},
{
value: "Sniper heart(W)",
label: "Sniper heart(W)",
},
{
value: "Blood sucker(w)",
label: "Blood sucker(w)",
},
{
value: "Graceful draw(w)",
label: "Graceful draw(w)",
},
{
value: "Bullet speed(W)",
label: "Bullet speed(W)",
},
];
pieceOptions = [
{
value: null,
label: "All",
},
{
value: "Testimonial",
label: "Testimonial",
},
{
value: "Shoulder",
label: "Shoulder",
},
{
value: "Left Arm",
label: "Left Arm",
},
{
value: "Abdomen",
label: "Abdomen",
},
{
value: "Left Leg",
label: "Left Leg",
},
{
value: "Weapon Head",
label: "Weapon Head",
},
{
value: "Chest",
label: "Chest",
},
{
value: "Right Arm",
label: "Right Arm",
},
{
value: "Right Leg",
label: "Right Leg",
},
{
value: "Blueprint",
label: "Blueprint",
},
{
value: "Sight",
label: "Sight",
},
{
value: "Stock",
label: "Stock",
},
{
value: "Trigger",
label: "Trigger",
},
{
value: "Ammo",
label: "Ammo",
},
{
value: "Bolt",
label: "Bolt",
},
{
value: "Barrel",
label: "Barrel",
},
{
value: "Grip",
label: "Grip",
},
{
value: "Clip",
label: "Clip",
},
];
sortOptions = [
{
value: "1|1",
label: "Recently",
},
{
value: "2|1",
label: "Highest",
},
{
value: "2|0",
label: "Lowest",
},
{
value: "3|1",
label: "Quality",
},
{
value: "4|1",
label: "Level",
},
{
value: "5|1",
label: "Energy",
},
];
jobList = [
{
id: 0,
jobname: "raider",
jobType: true,
jobImg: require("../../assets/market/filter-left/raider.png"),
disImg: require("../../assets/market/filter-left/raider-disabled.png"),
},
{
id: 1,
jobname: "guardian",
jobType: true,
jobImg: require("../../assets/market/filter-left/guardian.png"),
disImg: require("../../assets/market/filter-left/guardian-disabled.png"),
},
{
id: 2,
jobname: "machinist",
jobType: true,
jobImg: require("../../assets/market/filter-left/machinist.png"),
disImg: require("../../assets/market/filter-left/machinist-disabled.png"),
},
{
id: 3,
jobname: "medic",
jobType: true,
jobImg: require("../../assets/market/filter-left/medic.png"),
disImg: require("../../assets/market/filter-left/medic-disabled.png"),
},
];
chipList = [
{
id: 0,
jobname: "raider",
jobType: true,
jobImg: require("../../assets/market/filter-left/hero-chip.png"),
disImg: require("../../assets/market/filter-left/hero-chip-disable.png"),
},
{
id: 1,
jobname: "guardian",
jobType: true,
jobImg: require("../../assets/market/filter-left/gun-chip.png"),
disImg: require("../../assets/market/filter-left/gun-chip-disable.png"),
},
];
pieceList = [
{
id: 0,
jobname: "raider",
jobType: true,
jobImg: require("../../assets/market/filter-left/hero-chip.png"),
disImg: require("../../assets/market/filter-left/hero-chip-disable.png"),
},
{
id: 1,
jobname: "guardian",
jobType: true,
jobImg: require("../../assets/market/filter-left/gun-chip.png"),
disImg: require("../../assets/market/filter-left/gun-chip-disable.png"),
},
];
private totalPage = 1;
private pageSize = 10;
private searchFilters: any = null;
private jobFilters: any = "1|2|3|4";
private orderAsc: any = 0;
private lvFilter: any = 1;
private qualityFilter: number = 1;
private durabilityFilter: any = null;
private orderMethod: any = 0;
private starts = 0;
private currentPage = 1;
private currencyTypeList = [];
private dataCache: Map<any, INftData[]> = new Map();
private isProcess = false;
private rewardModal: ZModal;
orderTimer: any = null;
loadingInstance: ElLoadingComponent;
chainManager = new ChainManager();
created() {
this.debounce = debounce(() => {
this.getMyNftList(this.starts);
}, 1500);
}
get accountId() {
return AppModule.accountId;
}
get isLogin() {
return !!UserModule.token && !!AppModule.step && AppModule.accountId;
}
get boxProxyAddress() {
return CONTRACT_ADDRESS[AppModule.chainId].nftProxy;
}
heroSearch(value: string) {
this.searchFilters = value;
this.debounce();
}
handSelect(value: string) {
this.searchFilters = value;
this.getMyNftList(this.starts);
}
handSortSelect(value: string) {
this.orderMethod = value.slice(0, 1);
this.orderAsc = value.slice(2, 3);
this.getMyNftList(this.starts);
}
jobStatus(item: any) {
this.jobList[item.id].jobType = !this.jobList[item.id].jobType;
let list = this.jobList.filter((item) => {
return item.jobType == true;
});
let array = list.map((item) => {
return item.id;
});
let newArray = array.map(function (index) {
return index + 1;
});
this.jobFilters = newArray.join("|");
this.getMyNftList(this.starts);
}
pieceStatus(item: any) {
this.pieceList[item.id].jobType = !this.pieceList[item.id].jobType;
let list = this.pieceList.filter((item) => {
return item.jobType == true;
});
let array = list.map((item) => {
return item.id;
});
let newArray = array.map(function (index) {
return index + 1;
});
this.jobFilters = newArray.join("|");
this.getMyNftList(this.starts);
}
chipStatus(item: any) {
this.chipList[item.id].jobType = !this.chipList[item.id].jobType;
let list = this.chipList.filter((item) => {
return item.jobType == true;
});
let array = list.map((item) => {
return item.id;
});
let newArray = array.map(function (index) {
return index + 1;
});
this.jobFilters = newArray.join("|");
this.getMyNftList(this.starts);
}
heroLevelChange(levelSlider: any) {
this.lvFilter = levelSlider;
this.getMyNftList(this.starts);
// this.$emit("heroLevelChange", levelSlider);
}
heroQualityChange(Quality: any) {
this.qualityFilter = Quality;
this.getMyNftList(this.starts);
}
heroDurabilityChange(durability: any) {
this.durabilityFilter = durability;
this.getMyNftList(this.starts);
}
handWeaponSelect(value: any) {
this.searchFilters = value;
this.getMyNftList(this.starts);
}
weaponSearch(value: string) {
this.searchFilters = value;
this.debounce();
}
weaponQualityChange(Quality: any) {
this.qualityFilter = Quality;
this.getMyNftList(this.starts);
}
weaponLevelChange(value: any) {
this.lvFilter = value;
this.getMyNftList(this.pageSize);
}
weaponDurabilityChange(durability: any) {
this.durabilityFilter = durability;
this.getMyNftList(this.starts);
}
chipSearch(value: string) {
this.searchFilters = value;
this.debounce();
}
handChipSelect(value: string) {
this.searchFilters = value;
this.getMyNftList(this.starts);
}
chipLevelChange(value: any) {
this.lvFilter = value;
this.getMyNftList(this.starts);
}
pieceSearch(value: string) {
this.searchFilters = value;
this.debounce();
}
handPieceSelect(value: any) {
this.searchFilters = value;
this.getMyNftList(this.starts);
}
toPage(pageNo: number) {
console.log("to page: ", pageNo);
// this.currentPage = pageNo
this.starts = (pageNo - 1) * 10;
this.getMyNftList(this.starts);
}
async getMyNftList(pageNo: number) {
if (!AppModule.accountId) {
return;
}
try{
this.showLoading();
const reqData: any = {
page_size: this.pageSize,
start: this.starts,
type: this.nftType == 4 ? 5 : this.nftType,
job_filters: this.jobFilters,
search_filters: this.searchFilters,
quality_filter: this.qualityFilter,
durability_filter: this.durabilityFilter,
lv_filter: this.lvFilter,
order_asc: this.orderAsc,
order_method: this.orderMethod,
};
const res: any = await queryMyNftList(reqData);
if (res.nfts) {
let list = res.nfts;
this.nftList = list.filter((item: any) => {
return item.details !== null;
});
// console.log(this.nftList, "-==========================");
if (res) {
const page = res;
this.totalPage = page.total || 1;
this.pageSize = page.page_size || 10;
this.starts = page.start;
this.currentPage = page.start / page.page_size + 1;
}
if (res.errcode == 0) {
this.hideLoading();
}else{
this.hideLoading();
}
}
}catch(err){
this.hideLoading()
}
}
async getCurrencyType() {
if (this.currencyTypeList.length > 0) {
return false;
}
const res: any = await getSupportedCurrenTypes();
this.currencyTypeList = res.list;
// this.value = this.options[0].address;
}
onNftTypeClicked(typeId: number) {
console.log("nft type clicked: ", typeId);
if (this.nftType !== typeId) {
this.nftType = typeId;
this.jobFilters = "1|2|3|4";
const jobList = this.jobList.map((item) => {
item.jobType = true;
});
const chipList = this.chipList.map((item) => {
item.jobType = true;
});
const pieceList = this.pieceList.map((item) => {
item.jobType = true;
});
this.qualityFilter = 1;
this.durabilityFilter = null;
this.lvFilter = 1;
console.log(jobList, "jobList");
this.searchFilters = null;
// this.fetchDatas(1);
this.getMyNftList(this.starts);
}
this.getCurrencyType();
}
sliderChange() {}
filterChange(id: number) {
console.log("filter change: ", id);
if (this.nftState !== id) {
this.nftState = id;
// this.fetchDatas(1);
}
}
private resetData() {
this.totalPage = 1;
this.pageSize = 10;
this.nftList.length = 0;
this.$forceUpdate();
}
@Watch("isLogin")
private accountChange() {
console.log("account change: ", AppModule.accountId);
if (this.isLogin) {
// this.fetchDatas(this.pageSize);
this.checkOrderHistory();
this.getMyNftList(this.starts);
this.getCurrencyType();
} else {
this.resetData();
}
}
showFilter(val: boolean) {
this.mobileFilterShow = val;
}
// async fetchDatas(pageNo: number) {
// if (!AppModule.accountId) {
// return;
// }
// const reqData: any = {
// account: AppModule.accountId,
// page: pageNo,
// type: this.nftType,
// };
// if (this.nftState > 0) {
// reqData.state = this.nftState - 1;
// }
// if (this.dataCache.has(reqData)) {
// this.nftList = this.dataCache.get(reqData)!;
// } else {
// this.nftList.length = 0;
// }
// const res: any = await getNftList(reqData);
// if (res.nfts) {
// this.nftList.length = 0;
// for (const data of res.nfts) {
// const nftData = parseNftData(data);
// this.nftList.push(nftData);
// }
// this.dataCache.set(reqData, this.nftList);
// }
// if (res.page) {
// const page = res.page;
// this.totalPage = page.total_pages || 1;
// this.pageSize = page.current_page || 1;
// }
// console.log(res);
// }
// toPage(pageNo: number) {
// console.log("to page: ", pageNo);
// // this.fetchDatas(pageNo);
// }
showLoading() {
this.loadingInstance = this.$loading({ background: "rgba(0, 0, 0, 0.8)" });
}
hideLoading() {
this.loadingInstance?.close();
}
async onActivateClick({ tokenId, type }: { tokenId: string; type: number }) {
console.log("onActivateClick: ", tokenId, type);
if (!this.isLogin) {
this.$message({
message: "You should login first",
type: "warning",
duration: 5 * 1000,
});
return;
}
if (this.isProcess) {
this.$message({
message: "Box open in process",
type: "warning",
duration: 5 * 1000,
});
return;
}
if (!this.boxProxyAddress) {
this.$message({
message: "You need to connect to supported network",
type: "warning",
duration: 5 * 1000,
});
return;
}
this.isProcess = true;
const reqData = {
token_id: tokenId,
};
this.showLoading();
let nonce, signature, nftNew;
try {
const res: any = await preActivateNFT(reqData);
nonce = res.nonce;
signature = res.signature;
nftNew = res.new_token_id;
} catch (err) {
console.log("pre activate err", err);
this.$message.error("activate nft with pre request error");
this.hideLoading();
this.isProcess = false;
return false;
}
try {
const result = await this.chainManager.activateOneNft(
this.boxProxyAddress,
tokenId,
nftNew,
type,
nonce,
signature
);
console.log("activate nft result: ", result);
const stateData = { token_id: tokenId, txhash: result.transactionHash };
localStorage.setItem(MYSTERY_BOX_CACHE, JSON.stringify(stateData));
this.hideLoading();
this.beginTraceOrderStatus(stateData);
} catch (err) {
console.log(err);
this.hideLoading();
this.isProcess = false;
this.$message.error("activate nft with error: " + err);
}
}
checkOrderHistory() {
const historyOrderId = localStorage.getItem(MYSTERY_BOX_CACHE);
if (historyOrderId && this.accountId) {
try {
const data = JSON.parse(historyOrderId);
this.beginTraceOrderStatus(data);
} catch (err) {
localStorage.removeItem(MYSTERY_BOX_CACHE);
}
}
}
beginTraceOrderStatus(cacheData: any) {
this.showOrderStatus = true;
this.isProcess = true;
this.loadingInstance?.close();
this.orderTimer = setInterval(() => {
this.getOrderStatus(cacheData);
}, 1000);
}
async getOrderStatus(data: any) {
console.log("getOrderStatus: ", data);
try {
const res: any = await queryActivateNFTState(data);
if (res.state === 1) {
// success
this.onOpenSuccess(res.nft);
}
} catch (err) {
console.log("query order status error", err);
}
}
resetTmpOrderId() {
if (this.orderTimer !== null) {
clearInterval(this.orderTimer);
this.orderTimer = null;
}
this.isProcess = false;
localStorage.removeItem(MYSTERY_BOX_CACHE);
this.loadingInstance?.close();
}
async onOpenSuccess(data: any) {
console.log("open success");
if (!this.isProcess) {
return;
}
this.resetTmpOrderId();
this.showOrderStatus = false;
const cardList: INftData[] = [];
const nftData = parseNftData(data);
cardList.push(nftData);
this.showRewardModal({
title: "NFT activate Success",
cardList,
});
// this.fetchDatas(this.pageSize);
// this.$alert('Congratulations', 'Open Success', { type: 'success', confirmButtonText: 'OK' })
}
showRewardModal(data: any) {
console.log("show reward modal with data: ", data);
this.rewardModal = createModal(RewardModal, data);
this.rewardModal.show();
}
}
</script>
<style lang="scss" scoped>
@import "../../scss/breakpoints.scss";
.mynft {
display: flex;
flex-direction: column;
// align-items: center;
background-image: url("../../assets/market/bg.png.png");
.container {
display: flex;
flex-direction: row;
width: 1440px;
max-width: 100%;
box-sizing: border-box;
.right-part {
width: 100%;
position: relative;
}
}
}
.mobile-top {
display: none;
}
.page-comp {
width: 100%;
}
.page-comp {
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, -50%);
}
.order-status {
transform: scale(0.3);
width: 220px;
height: 220px;
border-radius: 110px;
background: white;
display: flex;
justify-content: center;
align-items: center;
transform-origin: top;
position: fixed;
left: 100px;
top: 100px;
}
@include media("<desktop") {
.container {
flex-direction: column;
.wrapper {
margin-top: 80px;
margin-bottom: -76px;
padding: 0;
.left-bar {
flex-grow: 1;
width: 50% !important;
padding: 0 15px;
}
}
}
.searchPanel {
width: 100%;
}
.filterTablet {
padding-top: 40px;
width: 100%;
-webkit-transition: all 0.3s;
transition: all 0.3s;
height: auto;
}
.filterTablet.collapsed {
padding-top: 0;
opacity: 0;
height: 0;
z-index: -1;
overflow: hidden;
}
.searchResult {
padding: 2.5em 4em;
}
.searchResult .wrapper .btnFilter {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
text-transform: uppercase;
}
}
@media (min-width: 1024px) and (max-width: 1439px) {
.mynft {
font-size: 11px;
}
.mynft .container {
width: 1024px;
max-width: 100%;
}
}
@media (min-width: 768px) and (max-width: 1023px) {
.mynft {
font-size: 20px;
}
.container {
width: 768px;
}
}
@media (max-width: 767px) {
.mynft {
font-size: 11px;
}
}
@media (max-width: 767px) and (max-width: 320px) {
.mynft {
font-size: 9px;
}
}
@media (max-width: 767px) {
.container {
width: 375px;
}
.searchResult {
padding: 26px 20px;
}
.show {
display: flex !important;
}
}
</style>