Skip to content

Commit

Permalink
Merge pull request #267 from supreme2580/canvas_and_more_filters
Browse files Browse the repository at this point in the history
Canvas and more filters
  • Loading branch information
b-j-roberts authored Dec 4, 2024
2 parents b92f1a1 + e5f99c1 commit 091610c
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 47 deletions.
2 changes: 2 additions & 0 deletions backend/config/canvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type CanvasConfig struct {
Colors []string `json:"colors"`
VotableColors []string `json:"votableColors"`
ColorsBitWidth uint `json:"colorsBitwidth"`
Round uint `json:"round"`
}

var DefaultCanvasConfig = &CanvasConfig{
Expand Down Expand Up @@ -42,6 +43,7 @@ var DefaultCanvasConfig = &CanvasConfig{
"#00DDDD",
},
ColorsBitWidth: 5,
Round: 2,
}

var DefaultCanvasConfigPath = "../configs/canvas.config.json"
Expand Down
23 changes: 18 additions & 5 deletions backend/routes/canvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package routes

import (
"context"
"fmt"
"net/http"
"strconv"

"github.com/keep-starknet-strange/art-peace/backend/core"
routeutils "github.com/keep-starknet-strange/art-peace/backend/routes/utils"
Expand All @@ -19,7 +21,10 @@ func initCanvas(w http.ResponseWriter, r *http.Request) {
return
}

if core.ArtPeaceBackend.Databases.Redis.Exists(context.Background(), "canvas").Val() == 0 {
roundNumber := core.ArtPeaceBackend.CanvasConfig.Round
canvasKey := fmt.Sprintf("canvas-%d", roundNumber)

if core.ArtPeaceBackend.Databases.Redis.Exists(context.Background(), canvasKey).Val() == 0 {
totalBitSize := core.ArtPeaceBackend.CanvasConfig.Canvas.Width * core.ArtPeaceBackend.CanvasConfig.Canvas.Height * core.ArtPeaceBackend.CanvasConfig.ColorsBitWidth
totalByteSize := (totalBitSize / 8)
if totalBitSize%8 != 0 {
Expand All @@ -30,23 +35,31 @@ func initCanvas(w http.ResponseWriter, r *http.Request) {
// Create canvas
canvas := make([]byte, totalByteSize)
ctx := context.Background()
err := core.ArtPeaceBackend.Databases.Redis.Set(ctx, "canvas", canvas, 0).Err()
err := core.ArtPeaceBackend.Databases.Redis.Set(ctx, canvasKey, canvas, 0).Err()
if err != nil {
routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to initialize canvas")
return
}

routeutils.WriteResultJson(w, "Canvas initialized")
routeutils.WriteResultJson(w, fmt.Sprintf("Canvas for round %d initialized", roundNumber))
} else {
routeutils.WriteErrorJson(w, http.StatusConflict, "Canvas already initialized")
routeutils.WriteErrorJson(w, http.StatusConflict, fmt.Sprintf("Canvas for round %d already initialized", roundNumber))
}
}

func getCanvas(w http.ResponseWriter, r *http.Request) {
routeutils.SetupAccessHeaders(w)

// Get round number from query params, default to config round
roundNumber := r.URL.Query().Get("round")
if roundNumber == "" {
roundNumber = strconv.Itoa(int(core.ArtPeaceBackend.CanvasConfig.Round))
}

canvasKey := fmt.Sprintf("canvas-%s", roundNumber)

ctx := context.Background()
val, err := core.ArtPeaceBackend.Databases.Redis.Get(ctx, "canvas").Result()
val, err := core.ArtPeaceBackend.Databases.Redis.Get(ctx, canvasKey).Result()
if err != nil {
routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to get canvas")
return
Expand Down
55 changes: 55 additions & 0 deletions backend/routes/nft.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func InitNFTRoutes() {
http.HandleFunc("/get-nft-pixel-data", getNftPixelData)
// http.HandleFunc("/like-nft", LikeNFT)
// http.HandleFunc("/unlike-nft", UnLikeNFT)
http.HandleFunc("/get-liked-nfts", getLikedNFTs)
http.HandleFunc("/get-top-nfts", getTopNFTs)
http.HandleFunc("/get-hot-nfts", getHotNFTs)
if !core.ArtPeaceBackend.BackendConfig.Production {
Expand Down Expand Up @@ -548,3 +549,57 @@ func getHotNFTs(w http.ResponseWriter, r *http.Request) {
}
routeutils.WriteDataJson(w, string(nfts))
}

func getLikedNFTs(w http.ResponseWriter, r *http.Request) {
address := r.URL.Query().Get("address")
if address == "" || address == "0" {
routeutils.WriteErrorJson(w, http.StatusBadRequest, "Valid address required for liked NFTs")
return
}

pageLength, err := strconv.Atoi(r.URL.Query().Get("pageLength"))
if err != nil || pageLength <= 0 {
pageLength = 25
}
if pageLength > 50 {
pageLength = 50
}

page, err := strconv.Atoi(r.URL.Query().Get("page"))
if err != nil || page <= 0 {
page = 1
}
offset := (page - 1) * pageLength

query := `
SELECT
nfts.*,
COALESCE(like_count, 0) AS likes,
true as liked
FROM
nfts
LEFT JOIN (
SELECT
nftKey,
COUNT(*) AS like_count
FROM
nftlikes
GROUP BY
nftKey
) nftlikes ON nfts.token_id = nftlikes.nftKey
WHERE
nfts.token_id IN (
SELECT nftkey
FROM nftlikes
WHERE liker = $1
)
ORDER BY nfts.token_id DESC
LIMIT $2 OFFSET $3`

nfts, err := core.PostgresQueryJson[NFTData](query, address, pageLength, offset)
if err != nil {
routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to retrieve liked NFTs")
return
}
routeutils.WriteDataJson(w, string(nfts))
}
3 changes: 2 additions & 1 deletion configs/canvas.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,6 @@
"898D90",
"D4D7D9"
],
"colorsBitwidth": 5
"colorsBitwidth": 5,
"round": 2
}
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ services:
- POSTGRES_PASSWORD=password
- ART_PEACE_END_TIME=3000000000
- ART_PEACE_HOST=0328ced46664355fc4b885ae7011af202313056a7e3d44827fb24c9d3206aaa0
- ROUND_NUMBER=1
- ROUND_NUMBER=2
volumes:
- nfts:/app/nfts
consumer:
Expand All @@ -50,7 +50,7 @@ services:
restart: always
environment:
- POSTGRES_PASSWORD=password
- ROUND_NUMBER=1
- ROUND_NUMBER=2
volumes:
- nfts:/app/nfts
- worlds:/app/worlds
Expand Down Expand Up @@ -143,7 +143,7 @@ services:
- devnet
environment:
- REACT_APP_BASE_PIXEL_TIMER=30000
- REACT_APP_ROUND_NUMBER=1
- REACT_APP_ROUND_NUMBER=2
volumes:
- ./frontend/package.json:/app/package.json
- ./frontend/package-lock.json:/app/package-lock.json
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/configs/canvas.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,6 @@
"898D90",
"D4D7D9"
],
"colorsBitwidth": 5
"colorsBitwidth": 5,
"round": 2
}
7 changes: 7 additions & 0 deletions frontend/src/services/apiService.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,10 @@ export const getHotStencilsFn = async (params) => {
`get-hot-stencils?address=${queryAddress}&page=${page}&pageLength=${pageLength}&worldId=${params.worldId}`
);
};

export const getLikedNftsFn = async (params) => {
const { page, pageLength, queryAddress } = params;
return await fetchWrapper(
`get-liked-nfts?address=${queryAddress}&page=${page}&pageLength=${pageLength}`
);
};
89 changes: 55 additions & 34 deletions frontend/src/tabs/nfts/NFTs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
getNftsFn,
getNewNftsFn,
getTopNftsFn,
getHotNftsFn
getHotNftsFn,
getLikedNftsFn
} from '../../services/apiService.js';
import { PaginationView } from '../../ui/pagination.js';

Expand Down Expand Up @@ -94,61 +95,76 @@ const NFTsMainSection = (props) => {
};

const NFTsExpandedSection = (props) => {
const roundNumber = process.env.REACT_APP_ROUND_NUMBER || '0';
const imageURL = `${nftUrl}/nft/round-${roundNumber}/images/`;
const metadataURL = `${nftUrl}/nft/round-${roundNumber}/metadata/`;
const maxRound = parseInt(process.env.REACT_APP_ROUND_NUMBER || '1');
const [currentRound, setCurrentRound] = useState(maxRound);
const imageURL = `${nftUrl}/nft/round-${currentRound}/images/`;
const metadataURL = `${nftUrl}/nft/round-${currentRound}/metadata/`;

const handleRoundChange = (direction) => {
if (direction === 'prev' && currentRound > 1) {
setCurrentRound((prev) => prev - 1);
props.setAllNftPagination((prev) => ({ ...prev, page: 1 }));
} else if (direction === 'next' && currentRound < maxRound) {
setCurrentRound((prev) => prev + 1);
props.setAllNftPagination((prev) => ({ ...prev, page: 1 }));
}
};

return (
<div className='NFTs__all'>
<div className='NFTs__header'>
<h2 className='NFTs__heading'>Explore</h2>
<div className='NFTs__filters'>
{props.filters.map((filter, index) => {
return (
<div
key={index}
className={`NFTs__button NFTs__filter ${
props.activeFilter === filter ? 'NFTs__button--selected' : ''
}`}
onClick={() => props.setActiveFilter(filter)}
>
{filter}
</div>
);
})}
{props.filters.map((filter, index) => (
<div
key={index}
className={`NFTs__button NFTs__filter ${
props.activeFilter === filter ? 'NFTs__button--selected' : ''
}`}
onClick={() => props.setActiveFilter(filter)}
>
{filter}
</div>
))}
<div
className='NFTs__button NFTs__filter'
onClick={() => handleRoundChange('prev')}
>
{'<'}
</div>
<div className='NFTs__button NFTs__filter'>
{`Round ${currentRound}`}
</div>
<div
className='NFTs__button NFTs__filter'
onClick={() => handleRoundChange('next')}
>
{'>'}
</div>
</div>
</div>

<div className='NFTs__all__container'>
<div className='NFTs__all__grid'>
{props.allNfts.map((nft, index) => {
return (
{currentRound === maxRound &&
(props.allNfts.length > 0 || props.activeFilter !== 'liked') &&
props.allNfts.map((nft, index) => (
<NFTItem
key={index}
{...nft}
address={props.address}
account={props.account}
estimateInvokeFee={props.estimateInvokeFee}
artPeaceContract={props.artPeaceContract}
canvasNftContract={props.canvasNftContract}
tokenId={nft.tokenId}
position={nft.position}
image={imageURL + 'nft-' + nft.tokenId + '.png'}
metadata={metadataURL + 'nft-' + nft.tokenId + '.json'}
width={nft.width}
height={nft.height}
name={nft.name}
blockNumber={nft.blockNumber}
likes={nft.likes}
liked={nft.liked}
minter={nft.minter}
queryAddress={props.queryAddress}
updateLikes={props.updateLikes}
setTemplateOverlayMode={props.setTemplateOverlayMode}
setOverlayTemplate={props.setOverlayTemplate}
setActiveTab={props.setActiveTab}
/>
);
})}
))}
</div>
<PaginationView
data={props.allNfts}
Expand Down Expand Up @@ -178,7 +194,6 @@ const NFTs = (props) => {
const response = await fetchWrapper(getNFTByTokenId, { mode: 'cors' });
if (response.data) {
let newNFTs = [response.data, ...myNFTs];
// Remove duplicate tokenIds
let uniqueNFTs = newNFTs.filter(
(nft, index, self) =>
index === self.findIndex((t) => t.tokenId === nft.tokenId)
Expand Down Expand Up @@ -244,7 +259,7 @@ const NFTs = (props) => {
}, [props.queryAddress, myNftPagination.page, myNftPagination.pageLength]);

const [expanded, setExpanded] = useState(false);
const filters = ['hot', 'new', 'top'];
const filters = ['hot', 'new', 'top', 'liked'];
const [activeFilter, setActiveFilter] = useState(filters[0]);

useEffect(() => {
Expand Down Expand Up @@ -272,6 +287,12 @@ const NFTs = (props) => {
pageLength: allNftPagination.pageLength,
queryAddress: props.queryAddress
});
} else if (activeFilter === 'liked') {
result = await getLikedNftsFn({
page: allNftPagination.page,
pageLength: allNftPagination.pageLength,
queryAddress: props.queryAddress
});
} else {
result = await getNftsFn({
page: allNftPagination.page,
Expand All @@ -298,7 +319,7 @@ const NFTs = (props) => {
}
}
getNfts();
}, [props.queryAddress, expanded, allNftPagination]);
}, [props.queryAddress, expanded, allNftPagination, activeFilter]);

const resetPagination = () => {
setAllNftPagination((prev) => ({
Expand Down
6 changes: 3 additions & 3 deletions main-docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ services:
- POSTGRES_PASSWORD=password
- ART_PEACE_END_TIME=3000000000
- ART_PEACE_HOST=0328ced46664355fc4b885ae7011af202313056a7e3d44827fb24c9d3206aaa0
- ROUND_NUMBER=1
- ROUND_NUMBER=2
consumer:
build:
dockerfile: backend/Dockerfile.consumer
Expand All @@ -48,7 +48,7 @@ services:
restart: always
environment:
- POSTGRES_PASSWORD=password
- ROUND_NUMBER=1
- ROUND_NUMBER=2
volumes:
- nfts:/app/nfts
devnet:
Expand Down Expand Up @@ -140,7 +140,7 @@ services:
- devnet
environment:
- REACT_APP_BASE_PIXEL_TIMER=30000
- REACT_APP_ROUND_NUMBER=1
- REACT_APP_ROUND_NUMBER=2
volumes:
- ./frontend/package.json:/app/package.json
- ./frontend/package-lock.json:/app/package-lock.json
Expand Down

0 comments on commit 091610c

Please sign in to comment.