Compare commits
No commits in common. "main" and "gh-pages" have entirely different histories.
@ -1,10 +0,0 @@
|
||||
MINIO_ENDPOINT=
|
||||
MINIO_ACCESS_KEY=
|
||||
MINIO_SECRET_KEY=
|
||||
MINIO_BUCKET=
|
||||
|
||||
PEERTUBE_FEED_URL=
|
||||
|
||||
UMAMI_ENABLED=
|
||||
UMAMI_SCRIPT_URL=
|
||||
UMAMI_WEBSITE_ID=
|
@ -1,30 +0,0 @@
|
||||
name: deploy
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "20.x"
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- run: echo "COMMIT_SHORT_SHA=`git rev-parse --short HEAD`" >> $GITHUB_ENV
|
||||
- run: npm run build
|
||||
env:
|
||||
MINIO_ENDPOINT: ${{ vars.MINIO_ENDPOINT }}
|
||||
MINIO_ACCESS_KEY: ${{ vars.MINIO_ACCESS_KEY }}
|
||||
MINIO_SECRET_KEY: ${{ vars.MINIO_SECRET_KEY }}
|
||||
MINIO_BUCKET: ${{ vars.MINIO_BUCKET }}
|
||||
PEERTUBE_FEED_URL: ${{ vars.PEERTUBE_FEED_URL }}
|
||||
UMAMI_ENABLED: ${{ vars.UMAMI_ENABLED }}
|
||||
UMAMI_SCRIPT_URL: ${{ vars.UMAMI_SCRIPT_URL }}
|
||||
UMAMI_WEBSITE_ID: ${{ vars.UMAMI_WEBSITE_ID }}
|
||||
- run: npx wrangler pages deploy out --project-name=$CF_PROJECT_NAME --branch=$GITHUB_REF_NAME
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ vars.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
|
||||
CF_PROJECT_NAME: ${{ vars.CF_PROJECT_NAME }}
|
30
.github/workflows/jobs.yaml
vendored
30
.github/workflows/jobs.yaml
vendored
@ -1,30 +0,0 @@
|
||||
name: deploy
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- run: echo "COMMIT_SHORT_SHA=`git rev-parse --short HEAD`" >> $GITHUB_ENV
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 21
|
||||
cache: "npm"
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
env:
|
||||
MINIO_ENDPOINT: ${{ secrets.MINIO_ENDPOINT }}
|
||||
MINIO_ACCESS_KEY: ${{ secrets.MINIO_ACCESS_KEY }}
|
||||
MINIO_SECRET_KEY: ${{ secrets.MINIO_SECRET_KEY }}
|
||||
MINIO_BUCKET: ${{ secrets.MINIO_BUCKET }}
|
||||
PEERTUBE_FEED_URL: ${{ secrets.PEERTUBE_FEED_URL }}
|
||||
UMAMI_ENABLED: ${{ vars.UMAMI_ENABLED }}
|
||||
UMAMI_SCRIPT_URL: ${{ vars.UMAMI_SCRIPT_URL }}
|
||||
UMAMI_WEBSITE_ID: ${{ vars.UMAMI_WEBSITE_ID }}
|
||||
- uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./out
|
||||
cname: ig.rizaldy.club
|
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,8 +0,0 @@
|
||||
.next
|
||||
node_modules
|
||||
out
|
||||
.devbox
|
||||
.env*.local
|
||||
remoteImagesForOptimization
|
||||
public/nextImageExportOptimizer
|
||||
public/images/next-image-export-optimizer-hashes.json
|
1
404.html
Normal file
1
404.html
Normal file
@ -0,0 +1 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/_next/static/css/25b36cfcabf50304.css" as="style" crossorigin=""/><link rel="stylesheet" href="/_next/static/css/25b36cfcabf50304.css" crossorigin="" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" crossorigin="" nomodule="" src="/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="https://u.rizaldy.club/umami.js" data-website-id="8dd38b8f-90e1-4df9-91ff-622d7882f05c" defer="" data-nscript="beforeInteractive" crossorigin=""></script><script src="/_next/static/chunks/webpack-ee7e63bc15b31913.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/framework-1e817f2a1c5c711b.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/main-72cd581c1e9bd837.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_app-4f9a8d5bb2887a9b.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_error-b6491f42fb2263bb.js" defer="" crossorigin=""></script><script src="/_next/static/yOMHMNqsMpN-23tJUJ2XT/_buildManifest.js" defer="" crossorigin=""></script><script src="/_next/static/yOMHMNqsMpN-23tJUJ2XT/_ssgManifest.js" defer="" crossorigin=""></script></head><body><div id="__next"><div class="min-h-screen bg-white dark:bg-black dark:text-neutral-200"><nav class="flex py-2 border-b dark:border-neutral-800 hover:opacity-70"><div class="w-3/12 md:w-full lg:w-7/12 md:mx-11 lg:mx-auto"><div class="md:w-2/12"><a href="/"><img alt="not instagram™" src="https://s3.rizaldy.club/0x0/d43840c5ee4ec66a3bee3c6e2.png" class="w-full"/></a></div></div></nav><div class="flex items-center justify-between w-full my-5"><div class="md:w-11/12 lg:w-7/12 mx-auto"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div></div><footer class="flex py-4 text-center md:mt-10 mt-5"><div class="md:w-7/12 mx-auto font-semibold"><div class="md:text-sm mb-10"><a class="md:mx-4 mb-1 md:inline block hover:opacity-70" href="/static/about">About</a><a class="md:mx-4 mb-1 md:inline block hover:opacity-70" href="https://rizaldy.club">Blog</a><a class="md:mx-4 mb-1 md:inline block hover:opacity-70" href="https://edgy.social/@rizaldy">Mastodon</a><a class="md:mx-4 mb-1 md:inline block hover:opacity-70" href="https://bsky.app/profile/rizaldy.club">Bluesky</a><a class="mx-4 hover:opacity-70" href="https://github.com/faultables/ig.rizaldy.club">Source Code</a></div><div class="text-sm font-normal text-neutral-400"><p>© <!-- -->MMXXIV<!-- --> <a class="text-neutral-600 dark:text-neutral-200 hover:opacity-70" target="_blank" rel="noopener noreferer" href="https://github.com/faultables">faultables</a> <!-- -->• All media is licensed under<!-- --> <a class="underline hover:opacity-70" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a> <!-- -->unless stated otherwise •<!-- --> <a class="text-neutral-600 dark:text-neutral-200 hover:opacity-70" target="_blank" rel="noopener noreferer" href="https://github.com/faultables/ig.rizaldy.club/commit/1102852">1102852</a></p></div></div></footer></div></div><script id="__NEXT_DATA__" type="application/json" crossorigin="">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"yOMHMNqsMpN-23tJUJ2XT","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
1
_next/data/yOMHMNqsMpN-23tJUJ2XT/index.json
Normal file
1
_next/data/yOMHMNqsMpN-23tJUJ2XT/index.json
Normal file
File diff suppressed because one or more lines are too long
33
_next/static/chunks/framework-1e817f2a1c5c711b.js
Normal file
33
_next/static/chunks/framework-1e817f2a1c5c711b.js
Normal file
File diff suppressed because one or more lines are too long
1
_next/static/chunks/main-72cd581c1e9bd837.js
Normal file
1
_next/static/chunks/main-72cd581c1e9bd837.js
Normal file
File diff suppressed because one or more lines are too long
1
_next/static/chunks/pages/_app-4f9a8d5bb2887a9b.js
Normal file
1
_next/static/chunks/pages/_app-4f9a8d5bb2887a9b.js
Normal file
File diff suppressed because one or more lines are too long
1
_next/static/chunks/pages/_error-b6491f42fb2263bb.js
Normal file
1
_next/static/chunks/pages/_error-b6491f42fb2263bb.js
Normal file
@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[820],{1981:function(n,_,u){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_error",function(){return u(8435)}])}},function(n){n.O(0,[774,888,179],function(){return n(n.s=1981)}),_N_E=n.O()}]);
|
1
_next/static/chunks/pages/index-c91f1d8faf4d92e1.js
Normal file
1
_next/static/chunks/pages/index-c91f1d8faf4d92e1.js
Normal file
@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[405],{5557:function(e,l,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/",function(){return t(5171)}])},5171:function(e,l,t){"use strict";t.r(l),t.d(l,{__N_SSG:function(){return p},default:function(){return f}});var r=t(5893),s=t(7294),a=t(7205);let n=(e,l)=>e===l?"border-t dark:border-neutral-400":"";var o=e=>{let{activeTab:l,setActiveTab:t}=e;return(0,r.jsxs)("div",{className:"flex items-center justify-center text-center gap-5 border-t mb-4 dark:border-neutral-800",children:[(0,r.jsx)("button",{onClick:()=>t("photos"),className:"uppercase tracking-tight font-semibold text-sm border-black pt-3 px-3 ".concat(n("photos",l)),children:"Photos"}),(0,r.jsx)("button",{onClick:()=>t("videos"),className:"uppercase tracking-tight font-semibold text-sm pt-3 px-3 border-black ".concat(n("videos",l)),children:"Videos"})]})},d=e=>{let{media:l,type:t,setOverlayContent:s,currentIndex:a,limitPerPage:n}=e;return(0,r.jsx)("main",{className:"grid grid-cols-3 gap-1",children:l.slice(a,n).map(e=>{let{id:l,url:a,previewPath:n,embedPath:o=a}=e;return(0,r.jsx)("a",{href:a,target:"_blank",rel:"noopener noreferer",className:"hover:opacity-70",onClick:e=>{e.preventDefault(),s({url:o,type:t})},children:(0,r.jsx)("img",{alt:a,loading:"lazy",src:n,className:"aspect-".concat(t," bg-neutral-100 dark:bg-neutral-900")})},l)})})},i=e=>{let{profile:l,totalPosts:t}=e;return(0,r.jsxs)("div",{className:"flex flex-warp",children:[(0,r.jsx)("div",{className:"lg:w-4/12 w-3/12 md:py-10 ml-3 md:ml-0 lg:px-20 md:px-10",children:(0,r.jsx)("img",{loading:"lazy",alt:l.display_name,src:l.avatar,className:"w-full rounded-full mx-auto border bg-neutral-100 border-gray-200 p-1 dark:border-neutral-800 dark:bg-black"})}),(0,r.jsxs)("div",{className:"lg:w-9/12 md:w-10/12 mb-5 md:p-5 ml-5",children:[(0,r.jsxs)("div",{className:"md:flex items-center",children:[(0,r.jsx)("h2",{className:"text-2xl font-semibold",children:l.username}),(0,r.jsxs)("div",{className:"md:ml-4 my-4",children:[(0,r.jsx)("a",{className:"rounded-md bg-gray-100 px-5 font-semibold py-2 md:ml-2 text-sm leading-relaxed dark:bg-neutral-800 hover:opacity-70",href:l.follow_url,children:"Follow"}),(0,r.jsx)("a",{className:"rounded-md bg-gray-100 px-5 font-semibold py-2 ml-2 text-sm leading-relaxed dark:bg-neutral-800 hover:opacity-70",href:l.message_url,children:"Message"})]})]}),(0,r.jsx)("div",{className:"md:my-5 my-3 font-bold text-sm",children:(0,r.jsxs)("p",{children:[t," posts"]})}),(0,r.jsx)("p",{className:"font-bold mb-1",children:l.display_name}),(0,r.jsx)("p",{children:l.about}),(0,r.jsx)("p",{className:"leading-loose font-semibold text-blue-900 dark:text-blue-200",children:(0,r.jsx)("a",{target:"_blank",className:"hover:underline",rel:"noopener noreferer",href:"https://".concat(l.link),children:l.link})})]})]})};let c=e=>{let{overlayContent:l}=e;return(null==l?void 0:l.type)===a.oZ.PHOTOS?(0,r.jsx)("img",{alt:null==l?void 0:l.url,src:null==l?void 0:l.url,className:"z-20 cursor-default"}):(null==l?void 0:l.type)===a.oZ.VIDEOS?(0,r.jsx)("iframe",{className:"md:w-6/12 w-full h-1/2",allow:"fullscreen",sandbox:"allow-same-origin allow-scripts allow-popups",src:null==l?void 0:l.url}):void 0};var m=e=>{let{overlayContent:l,closeOverlay:t}=e,s=(null==l?void 0:l.type)!==void 0;return(0,r.jsxs)("div",{onClick:t,className:"".concat(s?"bg-neutral-800/95 fixed w-full h-full left-0 top-0 cursor-pointer z-30":""),children:[s?(0,r.jsx)("p",{onClick:t,className:"fixed right-0 bottom-0 md:mx-5 my-5 text-white rounded text-sm text-center w-full z-30",children:'Click anywhere or press "Escape" to close'}):null,(0,r.jsx)("div",{className:"flex justify-center items-center ".concat(s?"h-full w-full":"h-0 w-0"),children:(0,r.jsx)(c,{overlayContent:l})})]})},u=t(356);let x=e=>{let{activeTab:l,photos:t,videos:s,...n}=e;return l===a.oZ.PHOTOS?(0,r.jsx)(d,{media:t,type:l,...n}):l===a.oZ.VIDEOS?(0,r.jsx)(d,{media:s,type:l,...n}):(0,r.jsx)("div",{className:"text-center pt-10 font-bold text-2xl",children:"nice try"})};var p=!0,f=e=>{let{photos:l,videos:t,totalPosts:n}=e,[d,c]=(0,s.useState)(a.oZ.PHOTOS),[p,f]=(0,s.useState)(0),[h,b]=(0,s.useState)(null),v=()=>b(null),g=e=>{let{keyCode:l}=e;l===a.O_&&v()};return(0,s.useEffect)(()=>(window.addEventListener("keydown",g),()=>{window.removeEventListener("keydown",g)}),[g]),(0,r.jsxs)(s.Fragment,{children:[(0,r.jsx)(i,{profile:u.N5,totalPosts:n}),(0,r.jsx)(o,{activeTab:d,setActiveTab:c}),(0,r.jsx)(m,{overlayContent:h,closeOverlay:v}),(0,r.jsx)(x,{currentIndex:p,setCurrentIndex:f,limitPerPage:a.Zv,activeTab:d,setOverlayContent:b,photos:l,videos:t})]})}}},function(e){e.O(0,[774,888,179],function(){return e(e.s=5557)}),_N_E=e.O()}]);
|
@ -0,0 +1 @@
|
||||
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[664],{1556:function(a,e,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/static/about",function(){return n(3414)}])},3414:function(a,e,n){"use strict";n.r(e);var i=n(5893);e.default=()=>(0,i.jsx)("div",{className:"p-2",children:(0,i.jsxs)("div",{className:"md:border p-5 md:w-8/12 md:shadow md:rotate-[-0.5deg] mx-auto text-neutral-600 dark:text-neutral-200 dark:border-neutral-800",children:[(0,i.jsx)("h2",{className:"font-bold text-3xl leading-loose mb-2 text-black dark:text-neutral-200",children:"Notes from @faultables"}),(0,i.jsxs)("p",{className:"mb-6",children:["Sebelumnya saya menjalankan ",(0,i.jsx)("em",{children:"instance"})," ",(0,i.jsx)("a",{href:"https://pixelfed.org",className:"underline hover:opacity-70",target:"_blank",rel:"noopener noreferer",children:"Pixelfed"})," ",'selama bertahun-tahun sebagai alternatif dari sosial media mainstream yang dijalankan oleh "big co". Pixelfed masih dalam tahap pengembangan, sehingga, adanya bug dan masalah acak lainnya adalah hal yang wajar.']}),(0,i.jsxs)("p",{className:"mb-6",children:["Disamping itu, Pixelfed sangat menjanjikan: menggunakan protokol"," ",(0,i.jsx)("a",{href:"https://www.w3.org/TR/activitypub/",className:"underline hover:opacity-70",target:"_blank",rel:"noopener noreferer",children:"ActivityPub"})," ",'sehingga bisa "berfederasi" dengan ',(0,i.jsx)("em",{children:"instance"})," lain, dan yang paling penting adalah"," ",(0,i.jsx)("a",{href:"https://github.com/pixelfed/pixelfed",classname:"underline hover:opacity-70",target:"_blank",rel:"noopener noreferer",children:"bersumber kode terbuka"})," ",(0,i.jsx)("strong",{children:"dan"}),' dikembangkan murni oleh komunitas. Pixelfed mendukung fitur standar untuk bersosial media seperti memperbaharui status, mengikuti pengguna, mengirim komentar, menyukai, intinya fitur bersosial apapun yang sudah menjadi mainstream. Meskipun saya sudah memiliki akun sosial media lainnya di "universe"'," ",(0,i.jsx)("a",{href:"https://joinmastodon.org",className:"underline hover:opacity-70",target:"_blank",rel:"noopener noreferer",children:"Mastodon"}),", saya memilih Pixelfed murni hanya untuk berbagi media dalam bentuk foto saja."]}),(0,i.jsx)("p",{className:"mb-6",children:"Tapi, ya, saya tidak menggunakan Pixelfed sesering itu. Saya melakukan optimasi gambar secara manual berikut menghapus metadata exif dan memotong gambar ke 1024px tanpa menggunakan fitur built-in (crop) karena terkadang fiturnya tidak berjalan sesuatu dengan yang harapkan."}),(0,i.jsx)("p",{className:"mb-6",children:'Secara teknis, menjalankan 2 aplikasi (Laravel & Horizon) plus MySQL bukanlah hal yang sulit dan mahal, namun bagaimanapun, saya tidak menggunakan "fitur sosial" yang ada di Pixelfed karena itulah yang saya inginkan sehingga terkesan seperti berlebihan.'}),(0,i.jsx)("p",{className:"mb-6",children:"Jika kamu seorang fotografer, kamu bisa mencoba Pixelfed. Kamu juga bisa berinteraksi dengan komunitas di jaringan yang sama—selama menggunakan protokol ActivityPub—karena Pixelfed adalah jaringan federasi!"}),(0,i.jsx)("p",{className:"mb-6",children:"Bagaimanapun, pilihan ini bukanlah pendekatan yang terbaik. Tapi setidaknya, ini tidak berlebihan, khususnya untuk saat ini."}),(0,i.jsx)("br",{}),(0,i.jsx)("p",{className:"mb-6",children:(0,i.jsx)("a",{href:"https://github.com/faultables",className:"hover:opacity-70",target:"_blank",rel:"noopener noreferer",children:"— faultables"})})]})})}},function(a){a.O(0,[774,888,179],function(){return a(a.s=1556)}),_N_E=a.O()}]);
|
1
_next/static/chunks/polyfills-c67a75d1b6f99dc8.js
Normal file
1
_next/static/chunks/polyfills-c67a75d1b6f99dc8.js
Normal file
File diff suppressed because one or more lines are too long
1
_next/static/chunks/webpack-ee7e63bc15b31913.js
Normal file
1
_next/static/chunks/webpack-ee7e63bc15b31913.js
Normal file
@ -0,0 +1 @@
|
||||
!function(){"use strict";var e,n,r,t,o={},u={};function i(e){var n=u[e];if(void 0!==n)return n.exports;var r=u[e]={exports:{}},t=!0;try{o[e](r,r.exports,i),t=!1}finally{t&&delete u[e]}return r.exports}i.m=o,e=[],i.O=function(n,r,t,o){if(r){o=o||0;for(var u=e.length;u>0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[r,t,o];return}for(var f=1/0,u=0;u<e.length;u++){for(var r=e[u][0],t=e[u][1],o=e[u][2],c=!0,l=0;l<r.length;l++)f>=o&&Object.keys(i.O).every(function(e){return i.O[e](r[l])})?r.splice(l--,1):(c=!1,o<f&&(f=o));if(c){e.splice(u--,1);var a=t();void 0!==a&&(n=a)}}return n},i.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(n,{a:n}),n},i.d=function(e,n){for(var r in n)i.o(n,r)&&!i.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.p="/_next/",n={272:0},i.O.j=function(e){return 0===n[e]},r=function(e,r){var t,o,u=r[0],f=r[1],c=r[2],l=0;if(u.some(function(e){return 0!==n[e]})){for(t in f)i.o(f,t)&&(i.m[t]=f[t]);if(c)var a=c(i)}for(e&&e(r);l<u.length;l++)o=u[l],i.o(n,o)&&n[o]&&n[o][0](),n[o]=0;return i.O(a)},(t=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))}();
|
3
_next/static/css/25b36cfcabf50304.css
Normal file
3
_next/static/css/25b36cfcabf50304.css
Normal file
File diff suppressed because one or more lines are too long
1
_next/static/yOMHMNqsMpN-23tJUJ2XT/_buildManifest.js
Normal file
1
_next/static/yOMHMNqsMpN-23tJUJ2XT/_buildManifest.js
Normal file
@ -0,0 +1 @@
|
||||
self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/pages/index-c91f1d8faf4d92e1.js"],"/_error":["static/chunks/pages/_error-b6491f42fb2263bb.js"],"/static/about":["static/chunks/pages/static/about-30f1ad42665a60b3.js"],sortedPages:["/","/_app","/_error","/static/about"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
1
_next/static/yOMHMNqsMpN-23tJUJ2XT/_ssgManifest.js
Normal file
1
_next/static/yOMHMNqsMpN-23tJUJ2XT/_ssgManifest.js
Normal file
@ -0,0 +1 @@
|
||||
self.__SSG_MANIFEST=new Set(["\u002F"]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|
@ -1,42 +0,0 @@
|
||||
import ExportedImage from "next-image-export-optimizer";
|
||||
|
||||
const Feed = ({
|
||||
media,
|
||||
type,
|
||||
setOverlayContent,
|
||||
currentIndex,
|
||||
limitPerPage,
|
||||
}) => (
|
||||
<main className="grid grid-cols-3 gap-1">
|
||||
{media
|
||||
.slice(currentIndex, limitPerPage)
|
||||
.map(({ id, url, previewPath, embedPath = url }) => (
|
||||
<a
|
||||
key={id}
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferer"
|
||||
className="hover:opacity-70"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
setOverlayContent({
|
||||
url: embedPath,
|
||||
type,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<ExportedImage
|
||||
alt={url}
|
||||
loading="lazy"
|
||||
src={previewPath}
|
||||
width="512"
|
||||
height="512"
|
||||
className={`aspect-${type} bg-neutral-100 dark:bg-neutral-900`}
|
||||
/>
|
||||
</a>
|
||||
))}
|
||||
</main>
|
||||
);
|
||||
|
||||
export default Feed;
|
@ -1,53 +0,0 @@
|
||||
import Link from "next/link";
|
||||
|
||||
import { YEAR_TO_BUMP } from "../constants";
|
||||
|
||||
const Footer = ({ license, links, repo, commitID }) => (
|
||||
<footer className="flex py-4 text-center md:mt-10 mt-5">
|
||||
<div className="md:w-7/12 mx-auto font-semibold">
|
||||
<div className="md:text-sm mb-10">
|
||||
{links.map(({ url, label }) => (
|
||||
<Link
|
||||
key={url + label}
|
||||
href={url}
|
||||
className="md:mx-4 mb-1 md:inline block hover:opacity-70"
|
||||
>
|
||||
{label}
|
||||
</Link>
|
||||
))}
|
||||
<Link href={repo} className="mx-4 hover:opacity-70">
|
||||
Source Code
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="text-sm font-normal text-neutral-400">
|
||||
<p>
|
||||
© {YEAR_TO_BUMP}{" "}
|
||||
<Link
|
||||
className="text-neutral-600 dark:text-neutral-200 hover:opacity-70"
|
||||
target="_blank"
|
||||
rel="noopener noreferer"
|
||||
href="https://faultables.net"
|
||||
>
|
||||
faultables
|
||||
</Link>{" "}
|
||||
• All media is licensed under{" "}
|
||||
<Link className="underline hover:opacity-70" href={license.url}>
|
||||
{license.name}
|
||||
</Link>{" "}
|
||||
unless stated otherwise •{" "}
|
||||
<Link
|
||||
className="text-neutral-600 dark:text-neutral-200 hover:opacity-70"
|
||||
target="_blank"
|
||||
rel="noopener noreferer"
|
||||
href={`${repo}/commit/${commitID}`}
|
||||
>
|
||||
{commitID}
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
|
||||
export default Footer;
|
@ -1,28 +0,0 @@
|
||||
import Link from "next/link";
|
||||
import ExportedImage from "next-image-export-optimizer";
|
||||
|
||||
const Navbar = ({ name, logo }) => (
|
||||
<nav className="flex py-2 border-b dark:border-neutral-800 hover:opacity-70">
|
||||
<div className="w-3/12 md:w-full lg:w-7/12 md:mx-11 lg:mx-auto">
|
||||
<div className="md:w-2/12">
|
||||
<Link href="/">
|
||||
{logo ? (
|
||||
<ExportedImage
|
||||
alt={name}
|
||||
src={logo}
|
||||
width={224}
|
||||
height={56}
|
||||
className="w-full"
|
||||
/>
|
||||
) : (
|
||||
<h1 className="font-bold leading-relaxed tracking-tight text-2xl text-neutral-800">
|
||||
{name}
|
||||
</h1>
|
||||
)}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
|
||||
export default Navbar;
|
@ -1,66 +0,0 @@
|
||||
import { MEDIA_TYPE } from "../constants";
|
||||
|
||||
const OverlayContent = ({ overlayContent }) => {
|
||||
if (overlayContent?.type === MEDIA_TYPE.PHOTOS) {
|
||||
return (
|
||||
<img
|
||||
alt={overlayContent?.url}
|
||||
src={overlayContent?.url}
|
||||
className="z-20 cursor-default"
|
||||
/>
|
||||
);
|
||||
} else if (overlayContent?.type === MEDIA_TYPE.VIDEOS) {
|
||||
return (
|
||||
<iframe
|
||||
className="md:w-6/12 w-full h-1/2"
|
||||
allow="fullscreen"
|
||||
sandbox="allow-same-origin allow-scripts allow-popups"
|
||||
src={overlayContent?.url}
|
||||
></iframe>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const Overlay = ({ overlayContent, closeOverlay }) => {
|
||||
const isOverlayOpen = overlayContent?.type !== undefined;
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={closeOverlay}
|
||||
className={`${
|
||||
isOverlayOpen
|
||||
? "bg-neutral-800/95 fixed w-full h-full left-0 top-0 cursor-pointer z-30"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
{isOverlayOpen ? (
|
||||
<p
|
||||
onClick={closeOverlay}
|
||||
className="fixed right-0 bottom-0 md:mx-5 my-5 text-white rounded text-sm text-center w-full z-30 md:bottom-10 px-2 leading-relaxed"
|
||||
>
|
||||
Click anywhere or press "Escape" to close
|
||||
<span className="px-2">|</span>
|
||||
<a
|
||||
className="underline"
|
||||
target="_blank"
|
||||
rel="noreferer noopener"
|
||||
href={overlayContent?.url}
|
||||
>
|
||||
Click here
|
||||
</a>{" "}
|
||||
to see the raw media
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
<div
|
||||
className={`flex justify-center items-center ${
|
||||
isOverlayOpen ? "h-full w-full" : "h-0 w-0"
|
||||
}`}
|
||||
>
|
||||
<OverlayContent overlayContent={overlayContent} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Overlay;
|
@ -1,52 +0,0 @@
|
||||
import ExportedImage from "next-image-export-optimizer";
|
||||
|
||||
const Profile = ({ profile, totalPosts }) => (
|
||||
<div className="flex flex-warp">
|
||||
<div className="lg:w-4/12 w-3/12 md:py-10 ml-3 md:ml-0 lg:px-20 md:px-10">
|
||||
<ExportedImage
|
||||
loading="lazy"
|
||||
alt={profile.display_name}
|
||||
src={profile.avatar}
|
||||
width={250}
|
||||
height={250}
|
||||
className="w-full rounded-full mx-auto border bg-neutral-100 border-gray-200 p-1 dark:border-neutral-800 dark:bg-black"
|
||||
/>
|
||||
</div>
|
||||
<div className="lg:w-9/12 md:w-10/12 mb-5 md:p-5 ml-5">
|
||||
<div className="md:flex items-center">
|
||||
<h2 className="text-2xl font-semibold">{profile.username}</h2>
|
||||
<div className="md:ml-4 my-4">
|
||||
<a
|
||||
className="rounded-md bg-gray-100 px-5 font-semibold py-2 md:ml-2 text-sm leading-relaxed dark:bg-neutral-800 hover:opacity-70"
|
||||
href={profile.follow_url}
|
||||
>
|
||||
Follow
|
||||
</a>
|
||||
<a
|
||||
className="rounded-md bg-gray-100 px-5 font-semibold py-2 ml-2 text-sm leading-relaxed dark:bg-neutral-800 hover:opacity-70"
|
||||
href={profile.message_url}
|
||||
>
|
||||
Message
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:my-5 my-3 font-bold text-sm">
|
||||
<p>{totalPosts} posts</p>
|
||||
</div>
|
||||
<p className="font-bold mb-1">{profile.display_name}</p>
|
||||
<p>{profile.about}</p>
|
||||
<p className="leading-loose font-semibold text-blue-900 dark:text-blue-200">
|
||||
<a
|
||||
target="_blank"
|
||||
className="hover:underline"
|
||||
rel="noopener noreferer"
|
||||
href={`https://${profile.link}`}
|
||||
>
|
||||
{profile.link}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Profile;
|
@ -1,27 +0,0 @@
|
||||
const isActiveTab = (currentTab, activeTab) =>
|
||||
currentTab === activeTab ? "border-t dark:border-neutral-400" : "";
|
||||
|
||||
const Tab = ({ activeTab, setActiveTab }) => (
|
||||
<div className="flex items-center justify-center text-center gap-5 border-t mb-4 dark:border-neutral-800">
|
||||
<button
|
||||
onClick={() => setActiveTab("photos")}
|
||||
className={`uppercase tracking-tight font-semibold text-sm border-black pt-3 px-3 ${isActiveTab(
|
||||
"photos",
|
||||
activeTab
|
||||
)}`}
|
||||
>
|
||||
Photos
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab("videos")}
|
||||
className={`uppercase tracking-tight font-semibold text-sm pt-3 px-3 border-black ${isActiveTab(
|
||||
"videos",
|
||||
activeTab
|
||||
)}`}
|
||||
>
|
||||
Videos
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Tab;
|
36
config.json
36
config.json
@ -1,36 +0,0 @@
|
||||
{
|
||||
"navbar": {
|
||||
"logotype": "not instagram™",
|
||||
"logo": "https://s3.rizaldy.club/0x0/d43840c5ee4ec66a3bee3c6e2.png"
|
||||
},
|
||||
"profile": {
|
||||
"avatar": "https://s3.rizaldy.club/0x0/IMG_6279.JPG",
|
||||
"username":"faultables",
|
||||
"follow_url": "https://edgy.social/@rizaldy",
|
||||
"message_url": "mailto:rizaldy@duck.com",
|
||||
"display_name": "rizaldy",
|
||||
"about": "SRE, DevOps, and everything in between",
|
||||
"link": "rizaldy.club"
|
||||
},
|
||||
"footer": {
|
||||
"repo": "https://forge.edgy.social/rizaldy/ig.rizaldy.club",
|
||||
"links": [
|
||||
{
|
||||
"label": "About",
|
||||
"url": "/static/about"
|
||||
},
|
||||
{
|
||||
"label": "Mastodon",
|
||||
"url": "https://edgy.social/@rizaldy"
|
||||
},
|
||||
{
|
||||
"label": "Bluesky",
|
||||
"url": "https://bsky.app/profile/rizaldy.club"
|
||||
}
|
||||
],
|
||||
"license": {
|
||||
"name": "CC BY-NC-SA 4.0",
|
||||
"url": "https://creativecommons.org/licenses/by-nc-sa/4.0/"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
export const MEDIA_PER_PAGE = 40;
|
||||
export const MEDIA_TYPE = {
|
||||
PHOTOS: "photos",
|
||||
VIDEOS: "videos",
|
||||
};
|
||||
|
||||
export const YEAR_TO_BUMP = "MMXXIV";
|
||||
export const ESCAPE_KEY = 27;
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"packages": ["nodejs@latest"]
|
||||
}
|
25
devbox.lock
25
devbox.lock
@ -1,25 +0,0 @@
|
||||
{
|
||||
"lockfile_version": "1",
|
||||
"packages": {
|
||||
"nodejs@latest": {
|
||||
"last_modified": "2024-01-14T03:55:27Z",
|
||||
"resolved": "github:NixOS/nixpkgs/dd5621df6dcb90122b50da5ec31c411a0de3e538#nodejs_21",
|
||||
"source": "devbox-search",
|
||||
"version": "21.5.0",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"store_path": "/nix/store/ybpqk26vz7k9grapsgx0sd900s0sp4sa-nodejs-21.5.0"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"store_path": "/nix/store/brnzb5xxgdx6bbicygz83ybi5inqp09v-nodejs-21.5.0"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"store_path": "/nix/store/yvgnx3lj8am9mqn30yr09sb4ia7qy3w8-nodejs-21.5.0"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"store_path": "/nix/store/nxfirpvaycr7wqzwl6wqifpdrqn7is7x-nodejs-21.5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1
index.html
Normal file
1
index.html
Normal file
File diff suppressed because one or more lines are too long
@ -1,19 +0,0 @@
|
||||
module.exports = {
|
||||
output: "export",
|
||||
images: {
|
||||
loader: "custom",
|
||||
deviceSizes: [1080, 1200, 1920],
|
||||
imageSizes: [128, 256, 384],
|
||||
},
|
||||
transpilePackages: ["next-image-export-optimizer"],
|
||||
env: {
|
||||
COMMIT_SHORT_SHA: process.env.COMMIT_SHORT_SHA || "HEAD",
|
||||
nextImageExportOptimizer_imageFolderPath: "public/images",
|
||||
nextImageExportOptimizer_exportFolderPath: "out",
|
||||
nextImageExportOptimizer_quality: "90",
|
||||
nextImageExportOptimizer_storePicturesInWEBP: "true",
|
||||
nextImageExportOptimizer_exportFolderName: "nextImageExportOptimizer",
|
||||
nextImageExportOptimizer_generateAndUseBlurImages: "true",
|
||||
nextImageExportOptimizer_remoteImageCacheTTL: "31536000",
|
||||
},
|
||||
};
|
3092
package-lock.json
generated
3092
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
@ -1,21 +0,0 @@
|
||||
{
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build && next-image-export-optimizer",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"minio": "^7.1.3",
|
||||
"next": "^14.0.4",
|
||||
"next-image-export-optimizer": "^1.12.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"xml2json": "^0.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.17",
|
||||
"postcss": "^8.4.33",
|
||||
"tailwindcss": "^3.4.1"
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
import "../styles/globals.css";
|
||||
|
||||
import Script from "next/script";
|
||||
|
||||
import Navbar from "../components/Navbar";
|
||||
import Footer from "../components/Footer";
|
||||
|
||||
import config from "../config.json";
|
||||
|
||||
const Content = ({ children }) => (
|
||||
<div className="flex items-center justify-between w-full my-5">
|
||||
<div className="md:w-11/12 lg:w-7/12 mx-auto">{children}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const App = ({ Component, pageProps }) => (
|
||||
<div className='min-h-screen bg-white dark:bg-black dark:text-neutral-200'>
|
||||
<Navbar name={config.navbar.logotype} logo={config.navbar.logo} />
|
||||
<Content>
|
||||
<Component {...pageProps} />
|
||||
</Content>
|
||||
<Footer
|
||||
repo={config.footer.repo}
|
||||
links={config.footer.links}
|
||||
license={config.footer.license}
|
||||
commitID={process.env.COMMIT_SHORT_SHA || "HEAD"}
|
||||
/>
|
||||
{process.env.UMAMI_ENABLED ? (
|
||||
<Script
|
||||
strategy="beforeInteractive"
|
||||
src={process.env.UMAMI_SCRIPT_URL}
|
||||
data-website-id={process.env.UMAMI_WEBSITE_ID}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default App;
|
@ -1,15 +0,0 @@
|
||||
import { Html, Head, Main, NextScript } from "next/document";
|
||||
|
||||
const Document = () => {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head />
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
};
|
||||
|
||||
export default Document;
|
114
pages/index.js
114
pages/index.js
@ -1,114 +0,0 @@
|
||||
import xml2json from "xml2json";
|
||||
|
||||
import { Client } from "minio";
|
||||
import { Fragment, useState, useEffect } from "react";
|
||||
|
||||
import { ESCAPE_KEY, MEDIA_PER_PAGE, MEDIA_TYPE } from "../constants";
|
||||
|
||||
import Tab from "../components/Tab";
|
||||
import Feed from "../components/Feed";
|
||||
import Profile from "../components/Profile";
|
||||
import Overlay from "../components/Overlay";
|
||||
|
||||
import config from "../config.json";
|
||||
|
||||
const Content = ({ activeTab, photos, videos, ...props }) => {
|
||||
if (activeTab === MEDIA_TYPE.PHOTOS) {
|
||||
return <Feed media={photos} type={activeTab} {...props} />;
|
||||
} else if (activeTab === MEDIA_TYPE.VIDEOS) {
|
||||
return <Feed media={videos} type={activeTab} {...props} />;
|
||||
} else {
|
||||
return <div className="text-center pt-10 font-bold text-2xl">nice try</div>;
|
||||
}
|
||||
};
|
||||
|
||||
const IndexPage = ({ photos, videos, totalPosts }) => {
|
||||
const [activeTab, setActiveTab] = useState(MEDIA_TYPE.PHOTOS);
|
||||
const [currentIndex, setCurrentIndex] = useState(0);
|
||||
const [overlayContent, setOverlayContent] = useState(null);
|
||||
|
||||
const closeOverlay = () => setOverlayContent(null);
|
||||
|
||||
const handleClose = ({ keyCode }) => {
|
||||
if (keyCode === ESCAPE_KEY) {
|
||||
closeOverlay();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("keydown", handleClose);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleClose);
|
||||
};
|
||||
}, [handleClose]);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Profile profile={config.profile} totalPosts={totalPosts} />
|
||||
<Tab activeTab={activeTab} setActiveTab={setActiveTab} />
|
||||
<Overlay overlayContent={overlayContent} closeOverlay={closeOverlay} />
|
||||
<Content
|
||||
currentIndex={currentIndex}
|
||||
setCurrentIndex={setCurrentIndex}
|
||||
limitPerPage={MEDIA_PER_PAGE}
|
||||
activeTab={activeTab}
|
||||
setOverlayContent={setOverlayContent}
|
||||
photos={photos}
|
||||
videos={videos}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export async function getStaticProps() {
|
||||
const minioEndpoint = process.env.MINIO_ENDPOINT;
|
||||
const minioBucket = process.env.MINIO_BUCKET;
|
||||
|
||||
const mc = new Client({
|
||||
endPoint: minioEndpoint,
|
||||
accessKey: process.env.MINIO_ACCESS_KEY,
|
||||
secretKey: process.env.MINIO_SECRET_KEY,
|
||||
});
|
||||
|
||||
const minioObjects = await new Promise((resolve, reject) => {
|
||||
const data = [];
|
||||
|
||||
const stream = mc.listObjectsV2(minioBucket, "photos", true, "");
|
||||
|
||||
stream.on("data", (obj) => data.push(obj.name));
|
||||
stream.on("error", reject);
|
||||
stream.on("end", () => {
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
|
||||
const photos = minioObjects.map((id) => ({
|
||||
id,
|
||||
url: `https://${minioEndpoint}/${minioBucket}/${id}`,
|
||||
previewPath: `https://${minioEndpoint}/${minioBucket}/${id}`,
|
||||
})).sort().reverse();
|
||||
|
||||
const getPeertubeFeeds = await fetch(process.env.PEERTUBE_FEED_URL);
|
||||
const peertubeFeeds = await getPeertubeFeeds.text();
|
||||
|
||||
const peertubeFeedsJSON = xml2json.toJson(peertubeFeeds, { object: true });
|
||||
const peertubeItems = peertubeFeedsJSON.rss.channel.item;
|
||||
|
||||
const videos = peertubeItems.map((item) => ({
|
||||
id: item.guid,
|
||||
url: item["media:embed"].url,
|
||||
previewPath: item["media:thumbnail"][0].url,
|
||||
}));
|
||||
|
||||
return {
|
||||
props: {
|
||||
config,
|
||||
photos,
|
||||
videos,
|
||||
totalPosts: photos.length + videos.length,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default IndexPage;
|
@ -1,93 +0,0 @@
|
||||
const About = () => (
|
||||
<div className="p-2">
|
||||
<div className="md:border p-5 md:w-8/12 md:shadow md:rotate-[-0.5deg] mx-auto text-neutral-600 dark:text-neutral-200 dark:border-neutral-800">
|
||||
<h2 className="font-bold text-3xl leading-loose mb-2 text-black dark:text-neutral-200">
|
||||
Notes from @faultables
|
||||
</h2>
|
||||
<p className="mb-6">
|
||||
Sebelumnya saya menjalankan <em>instance</em>{" "}
|
||||
<a
|
||||
href="https://pixelfed.org"
|
||||
className="underline hover:opacity-70"
|
||||
target="_blank"
|
||||
rel="noopener noreferer"
|
||||
>
|
||||
Pixelfed
|
||||
</a>{" "}
|
||||
selama bertahun-tahun sebagai alternatif dari sosial media mainstream
|
||||
yang dijalankan oleh "big co". Pixelfed masih dalam tahap pengembangan,
|
||||
sehingga, adanya bug dan masalah acak lainnya adalah hal yang wajar.
|
||||
</p>
|
||||
<p className="mb-6">
|
||||
Disamping itu, Pixelfed sangat menjanjikan: menggunakan protokol{" "}
|
||||
<a
|
||||
href="https://www.w3.org/TR/activitypub/"
|
||||
className="underline hover:opacity-70"
|
||||
target="_blank"
|
||||
rel="noopener noreferer"
|
||||
>
|
||||
ActivityPub
|
||||
</a>{" "}
|
||||
sehingga bisa "berfederasi" dengan <em>instance</em> lain, dan yang
|
||||
paling penting adalah{" "}
|
||||
<a
|
||||
href="https://github.com/pixelfed/pixelfed"
|
||||
classname="underline hover:opacity-70"
|
||||
target="_blank"
|
||||
rel="noopener noreferer"
|
||||
>
|
||||
bersumber kode terbuka
|
||||
</a>{" "}
|
||||
<strong>dan</strong> dikembangkan murni oleh komunitas. Pixelfed
|
||||
mendukung fitur standar untuk bersosial media seperti memperbaharui
|
||||
status, mengikuti pengguna, mengirim komentar, menyukai, intinya fitur
|
||||
bersosial apapun yang sudah menjadi mainstream. Meskipun saya sudah
|
||||
memiliki akun sosial media lainnya di "universe"{" "}
|
||||
<a
|
||||
href="https://joinmastodon.org"
|
||||
className="underline hover:opacity-70"
|
||||
target="_blank"
|
||||
rel="noopener noreferer"
|
||||
>
|
||||
Mastodon
|
||||
</a>
|
||||
, saya memilih Pixelfed murni hanya untuk berbagi media dalam bentuk
|
||||
foto saja.
|
||||
</p>
|
||||
<p className="mb-6">
|
||||
Tapi, ya, saya tidak menggunakan Pixelfed sesering itu. Saya melakukan
|
||||
optimasi gambar secara manual berikut menghapus metadata exif dan
|
||||
memotong gambar ke 1024px tanpa menggunakan fitur built-in (crop) karena
|
||||
terkadang fiturnya tidak berjalan sesuatu dengan yang harapkan.
|
||||
</p>
|
||||
<p className="mb-6">
|
||||
Secara teknis, menjalankan 2 aplikasi (Laravel & Horizon) plus MySQL
|
||||
bukanlah hal yang sulit dan mahal, namun bagaimanapun, saya tidak
|
||||
menggunakan "fitur sosial" yang ada di Pixelfed karena itulah yang saya
|
||||
inginkan sehingga terkesan seperti berlebihan.
|
||||
</p>
|
||||
<p className="mb-6">
|
||||
Jika kamu seorang fotografer, kamu bisa mencoba Pixelfed. Kamu juga bisa
|
||||
berinteraksi dengan komunitas di jaringan yang sama—selama menggunakan
|
||||
protokol ActivityPub—karena Pixelfed adalah jaringan federasi!
|
||||
</p>
|
||||
<p className="mb-6">
|
||||
Bagaimanapun, pilihan ini bukanlah pendekatan yang terbaik. Tapi
|
||||
setidaknya, ini tidak berlebihan, khususnya untuk saat ini.
|
||||
</p>
|
||||
<br />
|
||||
<p className="mb-6">
|
||||
<a
|
||||
href="https://rizaldy.club"
|
||||
className="hover:opacity-70"
|
||||
target="_blank"
|
||||
rel="noopener noreferer"
|
||||
>
|
||||
— faultables
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default About;
|
@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
const config = require("./config.json");
|
||||
|
||||
const minio = require("minio");
|
||||
const xml2json = require("xml2json");
|
||||
|
||||
const minioEndpoint = process.env.MINIO_ENDPOINT;
|
||||
const minioBucket = process.env.MINIO_BUCKET;
|
||||
|
||||
const mc = new minio.Client({
|
||||
endPoint: minioEndpoint,
|
||||
accessKey: process.env.MINIO_ACCESS_KEY,
|
||||
secretKey: process.env.MINIO_SECRET_KEY,
|
||||
});
|
||||
|
||||
const minioObjects = new Promise((resolve, reject) => {
|
||||
const data = [];
|
||||
|
||||
const stream = mc.listObjectsV2(minioBucket, "photos", true, "");
|
||||
|
||||
stream.on("data", (obj) => data.push(obj.name));
|
||||
stream.on("error", reject);
|
||||
stream.on("end", () => {
|
||||
resolve(data);
|
||||
});
|
||||
}).then((data) => {
|
||||
return data.map((id) => `https://${minioEndpoint}/${minioBucket}/${id}`);
|
||||
});
|
||||
|
||||
const getPeertubeFeeds = fetch(process.env.PEERTUBE_FEED_URL)
|
||||
.then((res) => res.text())
|
||||
.then((payload) => {
|
||||
const peertubeFeedsJSON = xml2json.toJson(payload, { object: true });
|
||||
const peertubeItems = peertubeFeedsJSON.rss.channel.item;
|
||||
|
||||
const videos = peertubeItems.map((item) => item["media:thumbnail"][0].url);
|
||||
|
||||
return videos;
|
||||
});
|
||||
|
||||
module.exports = Promise.all([minioObjects, getPeertubeFeeds]).then((data) => {
|
||||
return [...data[0], ...data[1], config.navbar.logo, config.profile.avatar];
|
||||
});
|
1
static/about.html
Normal file
1
static/about.html
Normal file
File diff suppressed because one or more lines are too long
@ -1,22 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
/* Somehow tailwind doesn't include this??? */
|
||||
.aspect-photos {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.aspect-videos {
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
mode: "jit",
|
||||
content: ["./pages/**/*.js", "./components/**/*.js"],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
Loading…
Reference in New Issue
Block a user