add pin for posts

pull/52/head
codemystery 4 years ago
parent 715daebdb4
commit af49765582

@ -202,7 +202,7 @@ const UserPage = () => {
</Card>
:
<Card width="100%" height="fit-content" p="0" px="3">
<Stories stories={posts} showFooter={tagFilter === null} />
<Stories stories={posts} showFooter={tagFilter === null} showPinned={true}/>
</Card>
}
</Box>

@ -96,6 +96,10 @@ const PostsPage = () => {
})
}
const onPinPost = async id => {
await requestApi.post(`/story/pin/${id}`)
getPosts()
}
return (
<>
<PageContainer1 >
@ -125,7 +129,7 @@ const PostsPage = () => {
<VStack mt="4">
{posts.map(post =>
<Box width="100%" key={post.id}>
<TextStoryCard story={post} showActions={true} mt="4" onEdit={() => editPost(post)} onDelete={() => onDeletePost(post.id)} />
<TextStoryCard story={post} showActions={true} mt="4" onEdit={() => editPost(post)} onDelete={() => onDeletePost(post.id)} onPin={() => onPinPost(post.id)} />
<Divider mt="5" />
</Box>
)}

@ -145,6 +145,11 @@ const PostsPage = () => {
setCurrentSeries(newSeries)
}
const onPinPost = async id => {
await requestApi.post(`/story/pin/${id}`)
getSeries()
}
return (
<>
<PageContainer1 >
@ -272,7 +277,7 @@ const PostsPage = () => {
<VStack mt="4">
{series.map(post =>
<Box width="100%" key={post.id}>
<TextStoryCard story={post} showActions={true} mt="4" onEdit={() => editSeries(post)} onDelete={() => onDeleteSeries(post.id)} showSource={false} />
<TextStoryCard story={post} showActions={true} mt="4" onEdit={() => editSeries(post)} onDelete={() => onDeleteSeries(post.id)} showSource={false} onPin={() => onPinPost(post.id)}/>
<Divider mt="5" />
</Box>
)}

@ -197,3 +197,25 @@ func GetSeries(c *gin.Context) {
c.JSON(http.StatusOK, common.RespSuccess(series))
}
type PinData struct {
TargetID string `json:"targetID"`
StoryID string `json:"storyID"`
}
func PinStory(c *gin.Context) {
storyID := c.Param("storyID")
u := user.CurrentUser(c)
if !models.IsStoryCreator(u.ID, storyID) {
c.JSON(http.StatusForbidden, common.RespError(e.NoPermission))
}
err := story.PinStory(storyID, u.ID)
if err != nil {
c.JSON(err.Status, common.RespError(err.Message))
return
}
c.JSON(http.StatusOK, common.RespSuccess(nil))
}

@ -54,6 +54,7 @@ func (s *Server) Start() error {
r.GET("/story/posts/drafts", IsLogin(), api.GetEditorDrafts)
r.GET("/story/posts/home/:filter", api.GetHomePosts)
r.POST("/story", IsLogin(), api.SubmitStory)
r.POST("/story/pin/:storyID", IsLogin(), api.PinStory)
r.POST("/story/series", api.GetSeries)
r.POST("/story/series/post/:id", IsLogin(), api.SubmitSeriesPost)
r.GET("/story/series/post/:id", api.GetSeriesPost)

@ -177,4 +177,13 @@ var sqlTables = map[string]string{
CREATE INDEX IF NOT EXISTS series_post_postid
ON series_post (post_id);
`,
"pin": `CREATE TABLE IF NOT EXISTS pin (
target_id VARCHAR(255),
story_id VARCHAR(255),
created DATETIME
);
CREATE INDEX IF NOT EXISTS pin_targetid
ON pin (target_id);
`,
}

@ -0,0 +1,51 @@
package story
import (
"database/sql"
"net/http"
"time"
"github.com/imdotdev/im.dev/server/pkg/db"
"github.com/imdotdev/im.dev/server/pkg/e"
)
func PinStory(storyID string, targetID string) *e.Error {
pinned := false
var nid string
err := db.Conn.QueryRow("SELECT target_id FROM pin WHERE target_id=? and story_id=?", targetID, storyID).Scan(&nid)
if err != nil && err != sql.ErrNoRows {
logger.Warn("query pinned error", "error", err)
return e.New(http.StatusInternalServerError, e.Internal)
}
if nid == targetID {
pinned = true
}
if pinned {
_, err = db.Conn.Exec("DELETE FROM pin WHERE target_id=? and story_id=?", targetID, storyID)
if err != nil {
logger.Warn("delete pin error", "error", err)
return e.New(http.StatusInternalServerError, e.Internal)
}
} else {
_, err = db.Conn.Exec("INSERT INTO pin (target_id,story_id,created) VALUES (?,?,?)", targetID, storyID, time.Now())
if err != nil {
logger.Warn("add pin error", "error", err)
return e.New(http.StatusInternalServerError, e.Internal)
}
}
return nil
}
func GetPinned(storyID string, targetID string) bool {
var nid string
err := db.Conn.QueryRow("SELECT target_id FROM pin WHERE target_id=? and story_id=?", targetID, storyID).Scan(&nid)
if err != nil {
return false
}
return true
}

@ -47,7 +47,21 @@ func UserPosts(tp string, user *models.User, uid string) (models.Stories, *e.Err
posts := GetPosts(user, rows)
sort.Sort(posts)
return posts, nil
pinned := make([]*models.Story, 0)
unpinned := make([]*models.Story, 0)
for _, post := range posts {
post.Pinned = GetPinned(post.ID, user.ID)
if post.Pinned {
pinned = append(pinned, post)
} else {
unpinned = append(unpinned, post)
}
}
newPosts := append(pinned, unpinned...)
return newPosts, nil
}
func UserDrafts(user *models.User, uid string) (models.Stories, *e.Error) {

@ -1,7 +1,6 @@
package models
import (
"fmt"
"time"
"github.com/imdotdev/im.dev/server/pkg/db"
@ -28,6 +27,7 @@ type Story struct {
RawTags []*Tag `json:"rawTags"`
Likes int `json:"likes"`
Liked bool `json:"liked"`
Pinned bool `json:"pinned,omitempty"`
Comments int `json:"comments"`
Views int `json:"views"`
Bookmarked bool `json:"bookmarked"`
@ -78,7 +78,6 @@ func (s SeriesPosts) Less(i, j int) bool {
func IsStoryCreator(userID string, storyID string) bool {
var nid string
err := db.Conn.QueryRow("SELECT creator FROM story WHERE id=?", storyID).Scan(&nid)
fmt.Println(userID, storyID, err)
if err != nil {
return false
}

@ -53,7 +53,7 @@ const Like = (props: Props) => {
/>}
</Tooltip>
<chakra.span layerStyle="textSecondary" fontWeight="600"><Count count={count}/></chakra.span>
<chakra.span opacity="0.8" fontSize={props.fontSize}><Count count={count} /></chakra.span>
</HStack>
)
}

@ -21,21 +21,19 @@ export const SimpleStoryCard = (props: Props) => {
return (
<VStack alignItems="left" spacing="0">
<Link href={getStoryUrl(story)}><Heading pb="2" fontSize=".9rem" cursor="pointer">{story.title}</Heading></Link>
<HStack pl="1" spacing="5" fontSize={size==='md'? '1rem' : ".9rem"}>
<Link href={`/${story.creator.username}`}><Text cursor="pointer">{story.creator.nickname}</Text></Link>
<HStack pl="1" spacing="2" fontSize={size==='md'? '1rem' : ".9rem"}>
<Link href={`/${story.creator.username}`}><Text cursor="pointer" fontSize="0.8rem">{story.creator.nickname}</Text></Link>
<HStack opacity="0.9">
<Like liked={story.liked} count={story.likes} storyID={story.id} fontSize="1rem"/>
<Like liked={story.liked} count={story.likes} storyID={story.id} fontSize="0.8rem"/>
</HStack>
<a href={`${getCommentsUrl(story)}#comments`}>
<HStack opacity="0.9" cursor="pointer">
{getSvgIcon("comments", "1rem")}
<Text ml="2">{story.comments}</Text>
<HStack opacity="0.9" cursor="pointer" spacing="3">
{getSvgIcon("comments1", "0.9rem")}
<Text fontSize="0.8rem" opacity="0.8">{story.comments}</Text>
</HStack>
</a>
<Box style={{marginLeft: '4px'}}><Bookmark storyID={story.id} bookmarked={story.bookmarked} height=".9rem"/></Box>
</HStack>
</VStack>
)

@ -9,13 +9,14 @@ interface Props {
card?: any
size?: 'sm' | 'md'
showFooter?: boolean
showPinned?: boolean
type?: string
highlight?: string
}
export const Stroies = (props: Props) => {
const { stories,card=StoryCard,showFooter=true,type="classic"} = props
const { stories,card=StoryCard,showFooter=true,type="classic",showPinned = false} = props
const borderColor = useColorModeValue(userCustomTheme.borderColor.light, userCustomTheme.borderColor.dark)
const Card = card
const showBorder = i => {
@ -34,7 +35,7 @@ export const Stroies = (props: Props) => {
<VStack alignItems="left">
{stories.map((story,i) =>
<Box py="2" borderBottom={showBorder(i)? `1px solid ${borderColor}`:null} key={story.id} px="1">
<Card story={story} size={props.size} type={type} highlight={props.highlight}/>
<Card story={story} size={props.size} type={type} highlight={props.highlight} showPinned={showPinned}/>
</Box>)}
</VStack>
{showFooter && <Center><Text layerStyle="textSecondary" fontSize="sm" py="4"></Text></Center>}

@ -30,14 +30,15 @@ export const StoryCard = (props: Props) => {
<StoryAuthor story={story} showFooter={false} size="md" />
<a href={getStoryUrl(story)} target="_blank">
<Layout alignItems={isLargeScreen ? "top" : "left"} cursor="pointer" pl="2" pt="1">
<VStack alignItems="left" spacing={type === "classic" ? 3 : 2} width={isLargeScreen && type === "classic" ? "calc(100% - 18rem)" : '100%'}>
<Heading size="md" fontSize={type === "classic" ? '1.4rem' : '1.2rem'}>
<VStack alignItems="left" spacing={type === "classic" ? 3 : 2} width={isLargeScreen && type === "classic" ? "calc(100% - 15rem)" : '100%'}>
<Heading size="md" fontSize={type === "classic" ? '1.3rem' : '1.2rem'}>
<Highlighter
highlightClassName="highlight-search-match"
textToHighlight={story.title}
searchWords={[props.highlight]}
/>
{story.type === IDType.Series && <Tag size="sm" mt="1" ml="2">SERIES</Tag>}
{story.type === IDType.Series && <Tag size="sm" ml="2" mt="2px">SERIES</Tag>}
{story.pinned && <Tag size="sm" ml="2" mt="2px"></Tag>}
</Heading>
{type !== "classic" && <HStack>{story.rawTags.map(t => <Text layerStyle="textSecondary" fontSize="md">#{t.name}</Text>)}</HStack>}
<Text layerStyle={type === "classic" ? "textSecondary" : null}>
@ -47,7 +48,7 @@ export const StoryCard = (props: Props) => {
searchWords={[props.highlight]}
/></Text>
</VStack>
{story.cover && type === "classic" && <Image src={story.cover} width="18rem" height="120px" pt={isLargeScreen ? 0 : 2} borderRadius="4px" />}
{story.cover && type === "classic" && <Image src={story.cover} width="15rem" height="120px" pt={isLargeScreen ? 0 : 2} borderRadius="4px" />}
</Layout>
</a>

@ -1,42 +1,73 @@
import React from "react"
import {chakra, Heading, VStack, Text, HStack,Button, Flex,PropsOf, Tag, useMediaQuery } from "@chakra-ui/react"
import { chakra, Heading, VStack, Text, HStack, Button, Flex, PropsOf, Tag, useMediaQuery, IconButton, Tooltip } from "@chakra-ui/react"
import { Story } from "src/types/story"
import moment from 'moment'
import { IDType } from "src/types/id"
import { getStoryUrl } from "utils/story"
import { FaPaperclip, FaRegTrashAlt, FaTrash } from "react-icons/fa"
import { getSvgIcon } from "components/svg-icon"
type Props = PropsOf<typeof chakra.div> & {
story: Story
showActions: boolean
onEdit?: any
onDelete?: any
onPin?: any
showSource?: boolean
}
export const TextStoryCard= (props:Props) =>{
const {story,showActions,onEdit,onDelete,showSource=true ,...rest} = props
export const TextStoryCard = (props: Props) => {
const { story, showActions, onEdit, onDelete, showSource = true,onPin, ...rest } = props
const [isSmallScreen] = useMediaQuery("(max-width: 768px)")
const Lay = isSmallScreen ? VStack : Flex
const gap = moment(story.created).fromNow()
return (
//@ts-ignore
<Lay justifyContent="space-between" alignItems={isSmallScreen? "left" : "center"} {...rest}>
<VStack alignItems="left" as="a" href={getStoryUrl(story)} spacing={{base: 4, md: 2}}>
<Lay justifyContent="space-between" alignItems={isSmallScreen ? "left" : "center"} {...rest}>
<VStack alignItems="left" as="a" href={getStoryUrl(story)} spacing={{ base: 4, md: 2 }}>
<Heading size="sm" display="flex" alignItems="center">
{showSource && <> {story.url ? <Tag size="sm" mr="2"></Tag> : <Tag size="sm" mr="2"></Tag>}</>}
{story.title ?story.title : 'No Title'}
{story.title ? story.title : 'No Title'}
</Heading>
<Text fontSize=".9rem">{gap}</Text>
</VStack>
{props.showActions && <HStack pt={{base: 3, md: 0}}>
<Button size="sm" colorScheme="teal" variant="outline" onClick={onEdit}>Edit</Button>
<Button size="sm" onClick={props.onDelete} variant="ghost">Delete</Button>
{props.showActions && <HStack pt={{ base: 3, md: 0 }} layerStyle="textSecondary">
<Tooltip label={story.pinned? "取消置顶" : "置顶"}>
<IconButton
aria-label="a icon button"
variant="ghost"
_focus={null}
icon={<FaPaperclip />}
onClick={onPin}
color={story.pinned? "teal" : null}
/>
</Tooltip>
<Tooltip label="编辑">
<IconButton
aria-label="a icon button"
variant="ghost"
_focus={null}
icon={getSvgIcon("edit", "1rem")}
onClick={onEdit}
/>
</Tooltip>
<Tooltip label="删除">
<IconButton
aria-label="a icon button"
variant="ghost"
_focus={null}
icon={<FaRegTrashAlt />}
onClick={props.onDelete}
/>
</Tooltip>
</HStack>}
</Lay>
</Lay>
)
}
}
export default TextStoryCard

@ -1,17 +1,20 @@
export function getSvgIcon(name,height="1.4rem") {
export function getSvgIcon(name, height = "1.4rem") {
let svg
switch (name) {
case "comments1":
svg = <svg fill="currentColor" height={height} viewBox="0 0 576 512"><path d="M569.9 441.1c-.5-.4-22.6-24.2-37.9-54.9 27.5-27.1 44-61.1 44-98.2 0-80-76.5-146.1-176.2-157.9C368.4 72.5 294.3 32 208 32 93.1 32 0 103.6 0 192c0 37 16.5 71 44 98.2-15.3 30.7-37.3 54.5-37.7 54.9-6.3 6.7-8.1 16.5-4.4 25 3.6 8.5 12 14 21.2 14 53.5 0 96.7-20.2 125.2-38.8 9.1 2.1 18.4 3.7 28 4.8 31.5 57.5 105.5 98 191.8 98 20.8 0 40.8-2.4 59.8-6.8 28.5 18.5 71.6 38.8 125.2 38.8 9.2 0 17.5-5.5 21.2-14 3.6-8.5 1.9-18.3-4.4-25zM155.4 314l-13.2-3-11.4 7.4c-20.1 13.1-50.5 28.2-87.7 32.5 8.8-11.3 20.2-27.6 29.5-46.4L83 283.7l-16.5-16.3C50.7 251.9 32 226.2 32 192c0-70.6 79-128 176-128s176 57.4 176 128-79 128-176 128c-17.7 0-35.4-2-52.6-6zm289.8 100.4l-11.4-7.4-13.2 3.1c-17.2 4-34.9 6-52.6 6-65.1 0-122-25.9-152.4-64.3C326.9 348.6 416 278.4 416 192c0-9.5-1.3-18.7-3.3-27.7C488.1 178.8 544 228.7 544 288c0 34.2-18.7 59.9-34.5 75.4L493 379.7l10.3 20.7c9.4 18.9 20.8 35.2 29.5 46.4-37.1-4.2-67.5-19.4-87.6-32.4z"></path></svg>
break
case "comments":
svg = <svg fill="currentColor" height={height} viewBox="0 0 512 512"><path d="M280 272H136c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h144c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zm96-96H136c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h240c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zM256 32C114.6 32 0 125.1 0 240c0 47.6 19.9 91.2 52.9 126.3C38 405.7 7 439.1 6.5 439.5c-6.6 7-8.4 17.2-4.6 26S14.4 480 24 480c61.5 0 110-25.7 139.1-46.3C192 442.8 223.2 448 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zm0 384c-28.3 0-56.3-4.3-83.2-12.8l-15.2-4.8-13 9.2c-23 16.3-58.5 35.3-102.6 39.6 12-15.1 29.8-40.4 40.8-69.6l7.1-18.7-13.7-14.6C47.3 313.7 32 277.6 32 240c0-97 100.5-176 224-176s224 79 224 176-100.5 176-224 176z"></path></svg>
break
case "best":
svg = <svg fill="currentColor" height={height} viewBox="0 0 448 512"><path d="M448 281.6c0-53.27-51.98-163.13-124.44-230.4-20.8 19.3-39.58 39.59-56.22 59.97C240.08 73.62 206.28 35.53 168 0 69.74 91.17 0 209.96 0 281.6 0 408.85 100.29 512 224 512c.53 0 1.04-.08 1.58-.08.32 0 .6.08.92.08 1.88 0 3.71-.35 5.58-.42C352.02 507.17 448 406.04 448 281.6zm-416 0c0-50.22 47.51-147.44 136.05-237.09 27.38 27.45 52.44 56.6 73.39 85.47l24.41 33.62 26.27-32.19a573.83 573.83 0 0130.99-34.95C379.72 159.83 416 245.74 416 281.6c0 54.69-21.53 104.28-56.28 140.21 12.51-35.29 10.88-75.92-8.03-112.02a357.34 357.34 0 00-10.83-19.19l-22.63-37.4-28.82 32.87-25.86 29.5c-24.93-31.78-59.31-75.5-63.7-80.54l-24.65-28.39-24.08 28.87C108.16 287 80 324.21 80 370.41c0 19.02 3.62 36.66 9.77 52.79C54.17 387.17 32 337.03 32 281.6zm193.54 198.32C162.86 479.49 112 437.87 112 370.41c0-33.78 21.27-63.55 63.69-114.41 6.06 6.98 86.48 109.68 86.48 109.68l51.3-58.52a334.43 334.43 0 019.87 17.48c23.92 45.66 13.83 104.1-29.26 134.24-17.62 12.33-39.14 19.71-62.37 20.73-2.06.07-4.09.29-6.17.31z"></path></svg>
svg = <svg fill="currentColor" height={height} viewBox="0 0 448 512"><path d="M448 281.6c0-53.27-51.98-163.13-124.44-230.4-20.8 19.3-39.58 39.59-56.22 59.97C240.08 73.62 206.28 35.53 168 0 69.74 91.17 0 209.96 0 281.6 0 408.85 100.29 512 224 512c.53 0 1.04-.08 1.58-.08.32 0 .6.08.92.08 1.88 0 3.71-.35 5.58-.42C352.02 507.17 448 406.04 448 281.6zm-416 0c0-50.22 47.51-147.44 136.05-237.09 27.38 27.45 52.44 56.6 73.39 85.47l24.41 33.62 26.27-32.19a573.83 573.83 0 0130.99-34.95C379.72 159.83 416 245.74 416 281.6c0 54.69-21.53 104.28-56.28 140.21 12.51-35.29 10.88-75.92-8.03-112.02a357.34 357.34 0 00-10.83-19.19l-22.63-37.4-28.82 32.87-25.86 29.5c-24.93-31.78-59.31-75.5-63.7-80.54l-24.65-28.39-24.08 28.87C108.16 287 80 324.21 80 370.41c0 19.02 3.62 36.66 9.77 52.79C54.17 387.17 32 337.03 32 281.6zm193.54 198.32C162.86 479.49 112 437.87 112 370.41c0-33.78 21.27-63.55 63.69-114.41 6.06 6.98 86.48 109.68 86.48 109.68l51.3-58.52a334.43 334.43 0 019.87 17.48c23.92 45.66 13.83 104.1-29.26 134.24-17.62 12.33-39.14 19.71-62.37 20.73-2.06.07-4.09.29-6.17.31z"></path></svg>
break
case "home":
svg = <svg fill="currentColor" height={height} viewBox="0 0 576 512"><path d="M541 229.16l-232.85-190a32.16 32.16 0 00-40.38 0L35 229.16a8 8 0 00-1.16 11.24l10.1 12.41a8 8 0 0011.2 1.19L96 220.62v243a16 16 0 0016 16h128a16 16 0 0016-16v-128l64 .3V464a16 16 0 0016 16l128-.33a16 16 0 0016-16V220.62L520.86 254a8 8 0 0011.25-1.16l10.1-12.41a8 8 0 00-1.21-11.27zm-93.11 218.59h.1l-96 .3V319.88a16.05 16.05 0 00-15.95-16l-96-.27a16 16 0 00-16.05 16v128.14H128V194.51L288 63.94l160 130.57z"></path></svg>
break
case "tags":
svg = <svg fill="currentColor" height={height} viewBox="0 0 640 512"><path d="M625.941 293.823L421.823 497.941c-18.746 18.746-49.138 18.745-67.882 0l-1.775-1.775 22.627-22.627 1.775 1.775c6.253 6.253 16.384 6.243 22.627 0l204.118-204.118c6.238-6.239 6.238-16.389 0-22.627L391.431 36.686A15.895 15.895 0 00380.117 32h-19.549l-32-32h51.549a48 48 0 0133.941 14.059L625.94 225.941c18.746 18.745 18.746 49.137.001 67.882zM252.118 32H48c-8.822 0-16 7.178-16 16v204.118c0 4.274 1.664 8.292 4.686 11.314l211.882 211.882c6.253 6.253 16.384 6.243 22.627 0l204.118-204.118c6.238-6.239 6.238-16.389 0-22.627L263.431 36.686A15.895 15.895 0 00252.118 32m0-32a48 48 0 0133.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882L293.823 497.941c-18.746 18.746-49.138 18.745-67.882 0L14.059 286.059A48 48 0 010 252.118V48C0 21.49 21.49 0 48 0h204.118zM144 124c-11.028 0-20 8.972-20 20s8.972 20 20 20 20-8.972 20-20-8.972-20-20-20m0-28c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.49-48 48-48z"></path></svg>
svg = <svg fill="currentColor" height={height} viewBox="0 0 640 512"><path d="M625.941 293.823L421.823 497.941c-18.746 18.746-49.138 18.745-67.882 0l-1.775-1.775 22.627-22.627 1.775 1.775c6.253 6.253 16.384 6.243 22.627 0l204.118-204.118c6.238-6.239 6.238-16.389 0-22.627L391.431 36.686A15.895 15.895 0 00380.117 32h-19.549l-32-32h51.549a48 48 0 0133.941 14.059L625.94 225.941c18.746 18.745 18.746 49.137.001 67.882zM252.118 32H48c-8.822 0-16 7.178-16 16v204.118c0 4.274 1.664 8.292 4.686 11.314l211.882 211.882c6.253 6.253 16.384 6.243 22.627 0l204.118-204.118c6.238-6.239 6.238-16.389 0-22.627L263.431 36.686A15.895 15.895 0 00252.118 32m0-32a48 48 0 0133.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882L293.823 497.941c-18.746 18.746-49.138 18.745-67.882 0L14.059 286.059A48 48 0 010 252.118V48C0 21.49 21.49 0 48 0h204.118zM144 124c-11.028 0-20 8.972-20 20s8.972 20 20 20 20-8.972 20-20-8.972-20-20-20m0-28c26.51 0 48 21.49 48 48s-21.49 48-48 48-48-21.49-48-48 21.49-48 48-48z"></path></svg>
break
case "post":
svg = <svg fill="currentColor" height={height} viewBox="0 0 384 512"><path d="M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zm-22.6 22.7c2.1 2.1 3.5 4.6 4.2 7.4H256V32.5c2.8.7 5.3 2.1 7.4 4.2l83.9 83.9zM336 480H48c-8.8 0-16-7.2-16-16V48c0-8.8 7.2-16 16-16h176v104c0 13.3 10.7 24 24 24h104v304c0 8.8-7.2 16-16 16zm-48-244v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm0 64v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12zm0 64v8c0 6.6-5.4 12-12 12H108c-6.6 0-12-5.4-12-12v-8c0-6.6 5.4-12 12-12h168c6.6 0 12 5.4 12 12z"></path></svg>
@ -20,7 +23,7 @@ export function getSvgIcon(name,height="1.4rem") {
svg = <svg fill="currentColor" height={height} viewBox="0 0 512 512"><path d="M512 256.01c0-9.98-5.81-18.94-14.77-22.81l-99.74-43.27 99.7-43.26c9-3.89 14.81-12.84 14.81-22.81s-5.81-18.92-14.77-22.79L271.94 3.33c-10.1-4.44-21.71-4.45-31.87-.02L14.81 101.06C5.81 104.95 0 113.9 0 123.87s5.81 18.92 14.77 22.79l99.73 43.28-99.7 43.26C5.81 237.08 0 246.03 0 256.01c0 9.97 5.81 18.92 14.77 22.79l99.72 43.26-99.69 43.25C5.81 369.21 0 378.16 0 388.14c0 9.97 5.81 18.92 14.77 22.79l225.32 97.76a40.066 40.066 0 0015.9 3.31c5.42 0 10.84-1.1 15.9-3.31l225.29-97.74c9-3.89 14.81-12.84 14.81-22.81 0-9.98-5.81-18.94-14.77-22.81l-99.72-43.26 99.69-43.25c9-3.89 14.81-12.84 14.81-22.81zM45.23 123.87l208.03-90.26.03-.02c1.74-.71 3.65-.76 5.45.02l208.03 90.26-208.03 90.27c-1.81.77-3.74.77-5.48 0L45.23 123.87zm421.54 264.27L258.74 478.4c-1.81.77-3.74.77-5.48 0L45.23 388.13l110.76-48.06 84.11 36.49a40.066 40.066 0 0015.9 3.31c5.42 0 10.84-1.1 15.9-3.31l84.11-36.49 110.76 48.07zm-208.03-41.87c-1.81.77-3.74.77-5.48 0L45.23 256 156 207.94l84.1 36.5a40.066 40.066 0 0015.9 3.31c5.42 0 10.84-1.1 15.9-3.31l84.1-36.49 110.77 48.07-208.03 90.25z"></path></svg>
break
case "explore":
svg = <svg fill="currentColor" height={height} viewBox="0 0 496 512"><path d="M264.97 272.97c9.38-9.37 9.38-24.57 0-33.94-9.37-9.37-24.57-9.37-33.94 0-9.38 9.37-9.38 24.57 0 33.94 9.37 9.37 24.57 9.37 33.94 0zM351.44 125c-2.26 0-4.51.37-6.71 1.16l-154.9 55.85c-7.49 2.7-13.1 8.31-15.8 15.8l-55.85 154.91c-5.65 15.67 10.33 34.27 26.4 34.27 2.26 0 4.51-.37 6.71-1.16l154.9-55.85c7.49-2.7 13.1-8.31 15.8-15.8l55.85-154.9c5.64-15.67-10.33-34.28-26.4-34.28zm-58.65 175.79l-140.1 50.51 50.51-140.11 140.11-50.51-50.52 140.11zM248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm0 464c-119.1 0-216-96.9-216-216S128.9 40 248 40s216 96.9 216 216-96.9 216-216 216z"></path></svg>
svg = <svg fill="currentColor" height={height} viewBox="0 0 496 512"><path d="M264.97 272.97c9.38-9.37 9.38-24.57 0-33.94-9.37-9.37-24.57-9.37-33.94 0-9.38 9.37-9.38 24.57 0 33.94 9.37 9.37 24.57 9.37 33.94 0zM351.44 125c-2.26 0-4.51.37-6.71 1.16l-154.9 55.85c-7.49 2.7-13.1 8.31-15.8 15.8l-55.85 154.91c-5.65 15.67 10.33 34.27 26.4 34.27 2.26 0 4.51-.37 6.71-1.16l154.9-55.85c7.49-2.7 13.1-8.31 15.8-15.8l55.85-154.9c5.64-15.67-10.33-34.28-26.4-34.28zm-58.65 175.79l-140.1 50.51 50.51-140.11 140.11-50.51-50.52 140.11zM248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm0 464c-119.1 0-216-96.9-216-216S128.9 40 248 40s216 96.9 216 216-96.9 216-216 216z"></path></svg>
break
case "feature":
svg = <svg fill="currentColor" height={height} viewBox="0 0 512 512"><path d="M493.7 232.4l-140.2-35 66.9-83.3c5.2-6.5 4.7-15.5-1.1-21.3-5.9-5.8-14.8-6.3-21.3-1.1l-83.4 66.7-35-140c-6.1-24.4-41-24.4-47.2 0l-35 140.2-83.3-67c-6.5-5.2-15.5-4.8-21.3 1.1-5.8 5.8-6.3 14.8-1.1 21.4l66.7 83.4-140 35C7.5 235.2 0 244.7 0 256c0 10.2 6.5 20.7 18.4 23.6l140.2 35-66.9 83.3c-5.2 6.5-4.7 15.5 1.1 21.3 5.6 5.5 14.5 6.5 21.3 1.1l83.4-66.7 35 140c3 11.9 13.3 18.4 23.6 18.4 4.5 0 19.4-2.1 23.6-18.4l35-140.2 83.3 67c6.9 5.5 15.8 4.4 21.3-1.1 5.8-5.8 6.3-14.8 1.1-21.3l-66.7-83.4 139.9-35c11.7-2.9 18.5-13.1 18.5-23.6-.1-10.3-6.6-20.6-18.4-23.6zM296 296l-40 160-40-160-160-40 160-40 40-160 40 160 160 40-160 40z"></path></svg>
@ -29,19 +32,25 @@ export function getSvgIcon(name,height="1.4rem") {
svg = <svg fill="currentColor" height={height} viewBox="0 0 512 512"><path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216zm-148.9 88.3l-81.2-59c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h14c6.6 0 12 5.4 12 12v146.3l70.5 51.3c5.4 3.9 6.5 11.4 2.6 16.8l-8.2 11.3c-3.9 5.3-11.4 6.5-16.8 2.6z"></path></svg>
break
case "search":
svg = <svg viewBox="0 0 200 200" fill="currentColor" height={height} ><g clipPath="url(#clip0)"><path d="M186.804 176.609l-44.092-44.091a4.054 4.054 0 00-2.905-1.197h-3.521c11.724-12.68 18.902-29.599 18.902-48.227C155.188 43.82 123.366 12 84.094 12 44.82 12 13 43.821 13 83.094c0 39.272 31.821 71.094 71.094 71.094 18.628 0 35.547-7.178 48.227-18.868v3.487c0 1.093.445 2.119 1.197 2.905l44.091 44.092a4.107 4.107 0 005.811 0l3.384-3.384a4.107 4.107 0 000-5.811zM84.094 143.25c-33.257 0-60.156-26.899-60.156-60.156s26.899-60.156 60.156-60.156 60.156 26.899 60.156 60.156-26.899 60.156-60.156 60.156z"></path></g><defs><clipPath><path transform="translate(13 12)" d="M0 0h175v175H0z"></path></clipPath></defs></svg>
svg = <svg viewBox="0 0 200 200" fill="currentColor" height={height} ><g clipPath="url(#clip0)"><path d="M186.804 176.609l-44.092-44.091a4.054 4.054 0 00-2.905-1.197h-3.521c11.724-12.68 18.902-29.599 18.902-48.227C155.188 43.82 123.366 12 84.094 12 44.82 12 13 43.821 13 83.094c0 39.272 31.821 71.094 71.094 71.094 18.628 0 35.547-7.178 48.227-18.868v3.487c0 1.093.445 2.119 1.197 2.905l44.091 44.092a4.107 4.107 0 005.811 0l3.384-3.384a4.107 4.107 0 000-5.811zM84.094 143.25c-33.257 0-60.156-26.899-60.156-60.156s26.899-60.156 60.156-60.156 60.156 26.899 60.156 60.156-26.899 60.156-60.156 60.156z"></path></g><defs><clipPath><path transform="translate(13 12)" d="M0 0h175v175H0z"></path></clipPath></defs></svg>
break
case "user":
svg = <svg fill="currentColor" height={height} viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM7.07 18.28c.43-.9 3.05-1.78 4.93-1.78s4.51.88 4.93 1.78C15.57 19.36 13.86 20 12 20s-3.57-.64-4.93-1.72zm11.29-1.45c-1.43-1.74-4.9-2.33-6.36-2.33s-4.93.59-6.36 2.33C4.62 15.49 4 13.82 4 12c0-4.41 3.59-8 8-8s8 3.59 8 8c0 1.82-.62 3.49-1.64 4.83zM12 6c-1.94 0-3.5 1.56-3.5 3.5S10.06 13 12 13s3.5-1.56 3.5-3.5S13.94 6 12 6zm0 5c-.83 0-1.5-.67-1.5-1.5S11.17 8 12 8s1.5.67 1.5 1.5S12.83 11 12 11z"></path></svg>
svg = <svg fill="currentColor" height={height} viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM7.07 18.28c.43-.9 3.05-1.78 4.93-1.78s4.51.88 4.93 1.78C15.57 19.36 13.86 20 12 20s-3.57-.64-4.93-1.72zm11.29-1.45c-1.43-1.74-4.9-2.33-6.36-2.33s-4.93.59-6.36 2.33C4.62 15.49 4 13.82 4 12c0-4.41 3.59-8 8-8s8 3.59 8 8c0 1.82-.62 3.49-1.64 4.83zM12 6c-1.94 0-3.5 1.56-3.5 3.5S10.06 13 12 13s3.5-1.56 3.5-3.5S13.94 6 12 6zm0 5c-.83 0-1.5-.67-1.5-1.5S11.17 8 12 8s1.5.67 1.5 1.5S12.83 11 12 11z"></path></svg>
break
case "favorites":
svg = <svg fill="currentColor" height={height} viewBox="0 0 496 512"><path d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 464c-119.1 0-216-96.9-216-216S128.9 40 248 40s216 96.9 216 216-96.9 216-216 216zm90.2-146.2C315.8 352.6 282.9 368 248 368s-67.8-15.4-90.2-42.2c-5.7-6.8-15.8-7.7-22.5-2-6.8 5.7-7.7 15.7-2 22.5C161.7 380.4 203.6 400 248 400s86.3-19.6 114.8-53.8c5.7-6.8 4.8-16.9-2-22.5-6.8-5.6-16.9-4.7-22.6 2.1zM168 240c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32z"></path></svg>
svg = <svg fill="currentColor" height={height} viewBox="0 0 496 512"><path d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 464c-119.1 0-216-96.9-216-216S128.9 40 248 40s216 96.9 216 216-96.9 216-216 216zm90.2-146.2C315.8 352.6 282.9 368 248 368s-67.8-15.4-90.2-42.2c-5.7-6.8-15.8-7.7-22.5-2-6.8 5.7-7.7 15.7-2 22.5C161.7 380.4 203.6 400 248 400s86.3-19.6 114.8-53.8c5.7-6.8 4.8-16.9-2-22.5-6.8-5.6-16.9-4.7-22.6 2.1zM168 240c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32z"></path></svg>
break
case "drafts":
svg = <svg fill="currentColor" height={height} viewBox="0 0 384 512"><path d="M369.9 97.9L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zm-22.6 22.7c2.1 2.1 3.5 4.6 4.2 7.4H256V32.5c2.8.7 5.3 2.1 7.4 4.2l83.9 83.9zM336 480H48c-8.8 0-16-7.2-16-16V48c0-8.8 7.2-16 16-16h176v104c0 13.3 10.7 24 24 24h104v304c0 8.8-7.2 16-16 16zM219.2 247.2l29.6 29.6c1.8 1.8 1.8 4.6 0 6.4L136.4 395.6l-30.1 4.3c-5.9.8-11-4.2-10.2-10.2l4.3-30.1 112.4-112.4c1.8-1.8 4.6-1.8 6.4 0zm64.4 1.2l-16.4 16.4c-1.8 1.8-4.6 1.8-6.4 0l-29.6-29.6c-1.8-1.8-1.8-4.6 0-6.4l16.4-16.4c5.9-5.9 15.4-5.9 21.2 0l14.8 14.8c5.9 5.8 5.9 15.3 0 21.2z"></path></svg>
break
case "share":
svg = <svg height={height} fill="currentColor" viewBox="0 0 448 512"><path d="M352 320c-28.6 0-54.2 12.5-71.8 32.3l-95.5-59.7c9.6-23.4 9.7-49.8 0-73.2l95.5-59.7c17.6 19.8 43.2 32.3 71.8 32.3 53 0 96-43 96-96S405 0 352 0s-96 43-96 96c0 13 2.6 25.3 7.2 36.6l-95.5 59.7C150.2 172.5 124.6 160 96 160c-53 0-96 43-96 96s43 96 96 96c28.6 0 54.2-12.5 71.8-32.3l95.5 59.7c-4.7 11.3-7.2 23.6-7.2 36.6 0 53 43 96 96 96s96-43 96-96c-.1-53-43.1-96-96.1-96zm0-288c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM96 320c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm256 160c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64z"></path></svg>
break
case "edit":
svg = <svg height={height} fill="currentColor" viewBox="0 0 512 512"><path d="M493.255 56.236l-37.49-37.49c-24.993-24.993-65.515-24.994-90.51 0L12.838 371.162.151 485.346c-1.698 15.286 11.22 28.203 26.504 26.504l114.184-12.687 352.417-352.417c24.992-24.994 24.992-65.517-.001-90.51zm-95.196 140.45L174 420.745V386h-48v-48H91.255l224.059-224.059 82.745 82.745zM126.147 468.598l-58.995 6.555-30.305-30.305 6.555-58.995L63.255 366H98v48h48v34.745l-19.853 19.853zm344.48-344.48l-49.941 49.941-82.745-82.745 49.941-49.941c12.505-12.505 32.748-12.507 45.255 0l37.49 37.49c12.506 12.506 12.507 32.747 0 45.255z"></path></svg>
break
default:
break;
break;
}
return svg

@ -40,6 +40,11 @@ export const interactionLinks: any[] = [
path: `${ReserveUrls.Interaction}/followers`,
disabled: false
},
{
title: 'Followers',
path: `${ReserveUrls.Interaction}/followers`,
disabled: false
},
]
export const searchLinks: any[] = [{

@ -24,6 +24,7 @@ export interface Story {
rawTags?: Tag[]
likes? : number
liked? : boolean
pinned?: boolean
comments? : number
bookmarked?: boolean
status?: number

Loading…
Cancel
Save