refactor, TODO remove mainObject
This commit is contained in:
parent
d48108429b
commit
cc8bc7f057
@ -1,19 +1,35 @@
|
|||||||
|
// src/app/animals/page.tsx
|
||||||
|
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import React, { useEffect, useState } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import Navigation from '../../components/Navigation'
|
|
||||||
import { fetchAnimalRecords } from '../../services/laconicQueryService'
|
|
||||||
import { MapPin } from 'lucide-react'
|
import { MapPin } from 'lucide-react'
|
||||||
|
import { fetchAnimalRecords } from '../../services/laconicQueryService'
|
||||||
|
import Navigation from '../../components/Navigation'
|
||||||
|
|
||||||
interface AnimalRecord {
|
interface AnimalRecord {
|
||||||
id: string
|
id: string
|
||||||
species: string
|
mainObject: string
|
||||||
location: {
|
location: {
|
||||||
latitude: number
|
latitude: number
|
||||||
longitude: number
|
longitude: number
|
||||||
}
|
}
|
||||||
description: string
|
description: string
|
||||||
imageUrl: string
|
imageUrl: string
|
||||||
|
species: string
|
||||||
|
// Records from Laconic Registry use `attributes` to store the content
|
||||||
|
// and have a separate creation timestamp
|
||||||
|
attributes?: {
|
||||||
|
mainObject: string
|
||||||
|
location: {
|
||||||
|
latitude: number
|
||||||
|
longitude: number
|
||||||
|
}
|
||||||
|
description: string
|
||||||
|
imageUrl: string
|
||||||
|
species: string
|
||||||
|
}
|
||||||
|
bondId?: string
|
||||||
createTime: string
|
createTime: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +97,7 @@ export default function AnimalsPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
{records.map((record, index) => (
|
{records.map((record, index) => (
|
||||||
<div
|
<div
|
||||||
key={`${record.id}-${index}`}
|
key={`${record.id}-${index}`}
|
||||||
|
@ -4,6 +4,7 @@ import { ANIMAL_LABELS } from './constants'
|
|||||||
|
|
||||||
export interface VisionAnalysisResult {
|
export interface VisionAnalysisResult {
|
||||||
description: string
|
description: string
|
||||||
|
mainObject: string // Added to store the primary detected object
|
||||||
isAnimal: boolean
|
isAnimal: boolean
|
||||||
rawResponse: any
|
rawResponse: any
|
||||||
}
|
}
|
||||||
@ -55,14 +56,22 @@ export async function analyzeImageWithVision(imageBuffer: Buffer): Promise<Visio
|
|||||||
ANIMAL_LABELS.includes(label.description.toLowerCase())
|
ANIMAL_LABELS.includes(label.description.toLowerCase())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Get the first animal label as main object
|
||||||
|
const mainObject = labels.find(label =>
|
||||||
|
ANIMAL_LABELS.includes(label.description.toLowerCase())
|
||||||
|
)?.description || 'Unknown'
|
||||||
|
|
||||||
|
const { description } = constructDescription(labels, objects)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: constructDescription(labels, objects),
|
description,
|
||||||
|
mainObject,
|
||||||
isAnimal,
|
isAnimal,
|
||||||
rawResponse: data.responses[0]
|
rawResponse: data.responses[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function constructDescription(labels: any[], objects: any[]): string {
|
function constructDescription(labels: any[], objects: any[]): { description: string } {
|
||||||
const topLabels = labels
|
const topLabels = labels
|
||||||
.filter(label => label.score > 0.7)
|
.filter(label => label.score > 0.7)
|
||||||
.map(label => label.description)
|
.map(label => label.description)
|
||||||
@ -74,15 +83,9 @@ function constructDescription(labels: any[], objects: any[]): string {
|
|||||||
.filter((value, index, self) => self.indexOf(value) === index)
|
.filter((value, index, self) => self.indexOf(value) === index)
|
||||||
.slice(0, 3)
|
.slice(0, 3)
|
||||||
|
|
||||||
let description = "In this image, I can see "
|
// Only include "The scene includes..." part as description
|
||||||
|
let description = "The scene includes "
|
||||||
|
description += topLabels.join(", ") + "."
|
||||||
|
|
||||||
if (topObjects.length > 0) {
|
return { description }
|
||||||
description += topObjects.join(", ") + ". "
|
|
||||||
}
|
|
||||||
|
|
||||||
if (topLabels.length > 0) {
|
|
||||||
description += "The scene includes " + topLabels.join(", ") + "."
|
|
||||||
}
|
|
||||||
|
|
||||||
return description
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// src/services/laconicQueryService.ts
|
// src/services/laconicQueryService.ts
|
||||||
//
|
|
||||||
interface AnimalRecord {
|
interface AnimalRecord {
|
||||||
|
id: string
|
||||||
|
mainObject: string
|
||||||
species: string
|
species: string
|
||||||
location: {
|
location: {
|
||||||
latitude: number
|
latitude: number
|
||||||
@ -8,9 +10,9 @@ interface AnimalRecord {
|
|||||||
}
|
}
|
||||||
description: string
|
description: string
|
||||||
imageUrl: string
|
imageUrl: string
|
||||||
|
createTime: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const LACONIC_GQL_ENDPOINT = process.env.NEXT_PUBLIC_LACONIC_GQL_ENDPOINT || 'https://laconicd-sapo.laconic.com/api'
|
const LACONIC_GQL_ENDPOINT = process.env.NEXT_PUBLIC_LACONIC_GQL_ENDPOINT || 'https://laconicd-sapo.laconic.com/api'
|
||||||
|
|
||||||
const ANIMAL_RECORDS_QUERY = `
|
const ANIMAL_RECORDS_QUERY = `
|
||||||
@ -88,7 +90,8 @@ export async function fetchAnimalRecords(): Promise<AnimalRecord[]> {
|
|||||||
longitude: location.longitude || 0
|
longitude: location.longitude || 0
|
||||||
},
|
},
|
||||||
description: attributesMap.description || 'No description',
|
description: attributesMap.description || 'No description',
|
||||||
imageUrl: attributesMap.imageUrl || null
|
imageUrl: attributesMap.imageUrl || null,
|
||||||
|
createTime: record.createTime || ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Filter out records without an imageUrl
|
// Filter out records without an imageUrl
|
||||||
|
Loading…
Reference in New Issue
Block a user