From 5cac10b163343ad1c017b2d6855a1a8c8ea86243 Mon Sep 17 00:00:00 2001 From: HSIAO PO WEN Date: Thu, 6 Jul 2023 09:08:38 +0800 Subject: [PATCH] feat: style Post component --- .nvmrc | 1 + packages/contracts/abi/UnirepApp.json | 194 +--------------------- packages/frontend/package.json | 5 +- packages/frontend/src/components/Post.tsx | 69 ++++++++ packages/frontend/src/index.tsx | 4 + packages/frontend/src/pages/PostList.tsx | 80 ++++----- packages/frontend/src/styles/main.css | 5 + yarn.lock | 22 +++ 8 files changed, 149 insertions(+), 231 deletions(-) create mode 100644 .nvmrc create mode 100644 packages/frontend/src/components/Post.tsx diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..8d2a4516 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18.16.1 \ No newline at end of file diff --git a/packages/contracts/abi/UnirepApp.json b/packages/contracts/abi/UnirepApp.json index c0f1d844..fc41b38d 100644 --- a/packages/contracts/abi/UnirepApp.json +++ b/packages/contracts/abi/UnirepApp.json @@ -1,193 +1 @@ -[ - { - "inputs": [ - { - "internalType": "contract Unirep", - "name": "_unirep", - "type": "address" - }, - { - "internalType": "contract IVerifier", - "name": "_dataVerifier", - "type": "address" - }, - { - "internalType": "uint48", - "name": "_epochLength", - "type": "uint48" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "epochKey", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "postId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "string", - "name": "content", - "type": "string" - } - ], - "name": "Post", - "type": "event" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "", "type": "uint256" } - ], - "name": "epochKeyPostIndex", - "outputs": [ - { "internalType": "uint256", "name": "", "type": "uint256" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { "internalType": "uint256", "name": "", "type": "uint256" }, - { "internalType": "uint256", "name": "", "type": "uint256" } - ], - "name": "epochKeyPostVoteMap", - "outputs": [ - { "internalType": "uint256", "name": "upVote", "type": "uint256" }, - { "internalType": "uint256", "name": "downVote", "type": "uint256" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256[]", - "name": "publicSignals", - "type": "uint256[]" - }, - { - "internalType": "uint256[8]", - "name": "proof", - "type": "uint256[8]" - }, - { "internalType": "string", "name": "content", "type": "string" } - ], - "name": "post", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { "internalType": "bytes32", "name": "", "type": "bytes32" } - ], - "name": "proofNullifier", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "epochKey", - "type": "uint256" - }, - { - "internalType": "uint48", - "name": "targetEpoch", - "type": "uint48" - }, - { - "internalType": "uint256", - "name": "fieldIndex", - "type": "uint256" - }, - { "internalType": "uint256", "name": "val", "type": "uint256" } - ], - "name": "submitAttestation", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "epochKey", - "type": "uint256" - }, - { - "internalType": "uint48", - "name": "targetEpoch", - "type": "uint48" - }, - { - "internalType": "uint256[]", - "name": "fieldIndices", - "type": "uint256[]" - }, - { "internalType": "uint256[]", "name": "vals", "type": "uint256[]" } - ], - "name": "submitManyAttestations", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "unirep", - "outputs": [ - { "internalType": "contract Unirep", "name": "", "type": "address" } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256[]", - "name": "publicSignals", - "type": "uint256[]" - }, - { - "internalType": "uint256[8]", - "name": "proof", - "type": "uint256[8]" - } - ], - "name": "userSignUp", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256[5]", - "name": "publicSignals", - "type": "uint256[5]" - }, - { - "internalType": "uint256[8]", - "name": "proof", - "type": "uint256[8]" - } - ], - "name": "verifyDataProof", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "stateMutability": "view", - "type": "function" - } -] +[{"inputs":[{"internalType":"contract Unirep","name":"_unirep","type":"address"},{"internalType":"contract IVerifier","name":"_dataVerifier","type":"address"},{"internalType":"uint48","name":"_epochLength","type":"uint48"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"epochKey","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"postId","type":"uint256"},{"indexed":false,"internalType":"string","name":"content","type":"string"}],"name":"Post","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochKeyPostIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochKeyPostVoteMap","outputs":[{"internalType":"uint256","name":"upVote","type":"uint256"},{"internalType":"uint256","name":"downVote","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"publicSignals","type":"uint256[]"},{"internalType":"uint256[8]","name":"proof","type":"uint256[8]"},{"internalType":"string","name":"content","type":"string"}],"name":"post","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"proofNullifier","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochKey","type":"uint256"},{"internalType":"uint48","name":"targetEpoch","type":"uint48"},{"internalType":"uint256","name":"fieldIndex","type":"uint256"},{"internalType":"uint256","name":"val","type":"uint256"}],"name":"submitAttestation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochKey","type":"uint256"},{"internalType":"uint48","name":"targetEpoch","type":"uint48"},{"internalType":"uint256[]","name":"fieldIndices","type":"uint256[]"},{"internalType":"uint256[]","name":"vals","type":"uint256[]"}],"name":"submitManyAttestations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unirep","outputs":[{"internalType":"contract Unirep","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"publicSignals","type":"uint256[]"},{"internalType":"uint256[8]","name":"proof","type":"uint256[8]"}],"name":"userSignUp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[5]","name":"publicSignals","type":"uint256[5]"},{"internalType":"uint256[8]","name":"proof","type":"uint256[8]"}],"name":"verifyDataProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 048c4b66..31060836 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -18,11 +18,14 @@ "@lexical/react": "^0.11.1", "@unirep-app/circuits": "1.0.0", "@unirep/core": "2.0.0-beta-3", + "boring-avatars": "^1.10.1", + "dayjs": "^1.11.9", "ethers": "^5.7.2", "file-loader": "^6.2.0", "iconoir-react": "^6.9.0", "lexical": "^0.11.1", - "mobx-react-lite": "^3.4.0" + "mobx-react-lite": "^3.4.0", + "react-twitter-login": "^1.5.0" }, "devDependencies": { "@babel/core": "^7.19.6", diff --git a/packages/frontend/src/components/Post.tsx b/packages/frontend/src/components/Post.tsx new file mode 100644 index 00000000..a6e107e3 --- /dev/null +++ b/packages/frontend/src/components/Post.tsx @@ -0,0 +1,69 @@ +import Avatar from 'boring-avatars' +import dayjs from 'dayjs' +import { ArrowDown, ArrowUp } from 'iconoir-react' + +export default function ({ + epochKey, + content = '', + publishedAt = new Date(), + commentCount = 0, + upCount = 0, + downCount = 0, +}: { + epochKey: string + content: string + publishedAt: Date + commentCount: number + upCount: number + downCount: number +}) { + const publishedTime = dayjs(publishedAt) + const publishedLabel = publishedTime.isBefore(dayjs()) + ? publishedTime.format('YYYY/MM/DD') + : publishedTime.fromNow() + + return ( +
+
+
+ +
+
+
+
+ + + {upCount - downCount} + + +
+
+

{content}

+
+ + {publishedLabel} + + + {commentCount} 則留言 + +
+
+
+
+ ) +} diff --git a/packages/frontend/src/index.tsx b/packages/frontend/src/index.tsx index 6ca55138..cd4f3e1a 100644 --- a/packages/frontend/src/index.tsx +++ b/packages/frontend/src/index.tsx @@ -1,5 +1,7 @@ // import './index.css' import './styles/main.css' +import dayjs from 'dayjs' +import relativeTime from 'dayjs/plugin/relativeTime' import { createRoot } from 'react-dom/client' import { BrowserRouter, Route, Routes } from 'react-router-dom' import Dashboard from './pages/Dashboard' @@ -8,6 +10,8 @@ import PostCreate from './pages/PostCreate' import PostList from './pages/PostList' import Start from './pages/Start' +dayjs.extend(relativeTime) + export default function App() { return ( diff --git a/packages/frontend/src/pages/PostList.tsx b/packages/frontend/src/pages/PostList.tsx index 61810b90..12a19644 100644 --- a/packages/frontend/src/pages/PostList.tsx +++ b/packages/frontend/src/pages/PostList.tsx @@ -1,68 +1,74 @@ import { Link } from 'react-router-dom' +import Post from '../components/Post' const posts = [ { id: '1', epochKey: 'epochKey-1', - publishedAt: '3 小時前', + publishedAt: new Date(), content: '今天真是一個美好的日子!我終於完成了我夢寐以求的目標:跑完全馬拉松!這個挑戰對我來說真的非常艱巨,但我堅持下來了。在這個過程中,我學到了很多關於毅力和奮鬥的價值。我要特別感謝我的家人和朋友對我一直以來的支持和鼓勵。無論你們在生活中面對什麼困難,只要你們相信自己,付出努力,你們一定可以實現自己的目標!今天,我真心覺得自己是最幸運的人。', + commentCount: 0, + upCount: 0, + downCount: 0, }, { id: '2', epochKey: 'epochKey-2', - publishedAt: '4 小時前', + publishedAt: new Date(), content: '最近我剛看完一本非常棒的書,推薦給大家!這本書叫做《思考快與慢》,作者是丹尼爾·卡尼曼。這本書深入探討了人類思考的方式和偏見。它教會了我們如何辨識和避免那些常常影響我們判斷力的錯誤和陷阱。我學到了很多關於認知心理學的知識,這些知識不僅適用於個人生活,還能幫助我們在工作和人際關係中做出更明智的決策。如果你對心理學或者是提升自己的思考能力感興趣,這本書絕對是值得一讀的!', + commentCount: 0, + upCount: 0, + downCount: 0, }, { id: '3', epochKey: 'epochKey-3', - publishedAt: '4 小時前', + publishedAt: new Date(), content: '剛剛和一群好友一起參加了一場令人驚喜的音樂會!我們聽到了一位非常出色的音樂家演奏,他的技巧和激情真是讓人難以置信。音樂會的現場氣氛也非常棒,大家都在跟著節奏搖擺,沉浸在美妙的音樂中。音樂總是有種神奇的力量,它能夠觸動人心,帶給我們情緒的共鳴。這次音樂會真的讓我重新燃起對音樂的熱愛,我想以後會更積極地參加各種音樂活動。如果你也喜歡音樂,不妨多花時間去欣賞和體驗。', + commentCount: 0, + upCount: 0, + downCount: 0, }, ] export default function PostList() { return ( -
-
- +
+
+
+ 嗨 🙌🏻 歡迎來到 Unirep Social TW +
+
+ 提供你 100% 匿名身份、安全發言的社群! +
+
+
+ ✏️ 撰寫貼文
-
    - {posts.map((post) => ( -
  • -
    -
    -
    - - {post.epochKey} - -
    - - {post.publishedAt} - -
    -

    {post.content}

    -
    - - -
    -
    -
    -
  • - ))} -
+
+
    + {posts.map((post) => ( +
  • + +
  • + ))} +
+
) } diff --git a/packages/frontend/src/styles/main.css b/packages/frontend/src/styles/main.css index b5c61c95..ceaf499e 100644 --- a/packages/frontend/src/styles/main.css +++ b/packages/frontend/src/styles/main.css @@ -1,3 +1,8 @@ @tailwind base; @tailwind components; @tailwind utilities; + +html, +body { + font-family: Inter, sans-serif; +} diff --git a/yarn.lock b/yarn.lock index 68324888..8af20c62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2969,6 +2969,11 @@ boolbase@^1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +boring-avatars@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/boring-avatars/-/boring-avatars-1.10.1.tgz#0e40811043cb3412bee38a0b6ca14f85fcdb0d2b" + integrity sha512-WcgHDeLrazCR03CDPEvCchLsUecZAZvs4F6FnMiGlTEjyQQf15Q5TRl4EUaAQ1dacvhPq7lC9EOTWkCojQ6few== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -3885,6 +3890,11 @@ crypto-browserify@^3.12.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-js@^3.1.9-1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" + integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== + crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" @@ -3963,6 +3973,11 @@ dateformat@^3.0.0: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== +dayjs@^1.11.9: + version "1.11.9" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a" + integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA== + debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -8284,6 +8299,13 @@ react-router@6.11.2: dependencies: "@remix-run/router" "1.6.2" +react-twitter-login@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/react-twitter-login/-/react-twitter-login-1.5.0.tgz#09903d4b216268f26ca0cfb696fa011fb91281a1" + integrity sha512-onS9dwZ+07+4mMi+2xh6w0KPgY6jkWEfVVom5RCzAolGkDKWTvEMIutkAm1s6O7QtFmam+mpKoMBF8Lwam5iKA== + dependencies: + crypto-js "^3.1.9-1" + react@^18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"