├── public ├── robots.txt └── favicon.ico ├── server └── tsconfig.json ├── tsconfig.json ├── postcss.config.js ├── assets └── css │ └── main.css ├── layouts └── default.vue ├── .gitignore ├── tailwind.config.js ├── nuxt.config.ts ├── app.vue ├── package.json ├── README.md ├── pages ├── index.vue ├── blog.vue ├── me.vue └── anilist.vue ├── components ├── Navbar.vue └── SpotifyCard.vue └── plugins └── socket.ts /public/robots.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/falsisdev/website/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | '@tailwindcss/postcss': {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /assets/css/main.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | @plugin "daisyui" { 3 | themes: sunset --default, silk --preferslight, abyss, dracula; 4 | } 5 | @plugin "@tailwindcss/typography"; -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./components/**/*.{js,vue,ts}", 5 | "./layouts/**/*.vue", 6 | "./pages/**/*.vue", 7 | "./plugins/**/*.{js,ts}", 8 | "./app.vue", 9 | "./error.vue", 10 | ], 11 | theme: { 12 | extend: {}, 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | devtools: { enabled: true }, 4 | modules: ["@nuxtjs/sanity", "@nuxt/icon"], 5 | css: ["~/assets/css/main.css"], 6 | sanity: { 7 | projectId: "5nqk6zg4", 8 | dataset: "production", 9 | }, 10 | postcss: { 11 | plugins: { 12 | '@tailwindcss/postcss': {}, 13 | autoprefixer: {}, 14 | }, 15 | }, 16 | compatibilityDate: "2025-01-01", 17 | }); -------------------------------------------------------------------------------- /app.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-app", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "nuxt build", 7 | "dev": "nuxt dev", 8 | "generate": "nuxt generate", 9 | "preview": "nuxt preview", 10 | "postinstall": "nuxt prepare" 11 | }, 12 | "dependencies": { 13 | "@nuxt/icon": "1.10.3", 14 | "@nuxtjs/sanity": "1.13.3", 15 | "@sanity/client": "^7.6.0", 16 | "@sanity/image-url": "^1.1.0", 17 | "nuxt": "^3.17.6", 18 | "swiper": "^11.2.10", 19 | "vue": "latest", 20 | "vue-router": "latest" 21 | }, 22 | "packageManager": "pnpm@9.7.0+sha512.dc09430156b427f5ecfc79888899e1c39d2d690f004be70e05230b72cb173d96839587545d09429b55ac3c429c801b4dc3c0e002f653830a420fa2dd4e3cf9cf", 23 | "devDependencies": { 24 | "@iconify-json/material-symbols": "^1.2.29", 25 | "@iconify-json/mdi": "^1.2.3", 26 | "@iconify-json/simple-icons": "^1.2.41", 27 | "@tailwindcss/postcss": "^4.1.11", 28 | "@tailwindcss/typography": "^0.5.16", 29 | "autoprefixer": "^10.4.21", 30 | "daisyui": "^5.0.43", 31 | "postcss": "^8.5.6", 32 | "tailwindcss": "^4.1.11" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nuxt Minimal Starter 2 | 3 | Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. 4 | 5 | ## Setup 6 | 7 | Make sure to install dependencies: 8 | 9 | ```bash 10 | # npm 11 | npm install 12 | 13 | # pnpm 14 | pnpm install 15 | 16 | # yarn 17 | yarn install 18 | 19 | # bun 20 | bun install 21 | ``` 22 | 23 | ## Development Server 24 | 25 | Start the development server on `http://localhost:3000`: 26 | 27 | ```bash 28 | # npm 29 | npm run dev 30 | 31 | # pnpm 32 | pnpm dev 33 | 34 | # yarn 35 | yarn dev 36 | 37 | # bun 38 | bun run dev 39 | ``` 40 | 41 | ## Production 42 | 43 | Build the application for production: 44 | 45 | ```bash 46 | # npm 47 | npm run build 48 | 49 | # pnpm 50 | pnpm build 51 | 52 | # yarn 53 | yarn build 54 | 55 | # bun 56 | bun run build 57 | ``` 58 | 59 | Locally preview production build: 60 | 61 | ```bash 62 | # npm 63 | npm run preview 64 | 65 | # pnpm 66 | pnpm preview 67 | 68 | # yarn 69 | yarn preview 70 | 71 | # bun 72 | bun run preview 73 | ``` 74 | 75 | Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. 76 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 44 | -------------------------------------------------------------------------------- /components/Navbar.vue: -------------------------------------------------------------------------------- 1 | 55 | -------------------------------------------------------------------------------- /components/SpotifyCard.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 85 | -------------------------------------------------------------------------------- /pages/blog.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | -------------------------------------------------------------------------------- /pages/me.vue: -------------------------------------------------------------------------------- 1 | 94 | -------------------------------------------------------------------------------- /plugins/socket.ts: -------------------------------------------------------------------------------- 1 | //@ts-nocheck 2 | export default defineNuxtPlugin((nuxtApp) => { 3 | nuxtApp.hook("page:loading:end", () => { 4 | var searchParams = new URLSearchParams(window.location.search); 5 | if (!searchParams.toString()) { 6 | const OPCODES = { 7 | INFO: 0, 8 | HELLO: 1, 9 | INIT: 2, 10 | HEARTBEAT: 3, 11 | }; 12 | const ws = new WebSocket("wss://api.lanyard.rest/socket"); //lanyard websocket 13 | 14 | /* EVENTS */ 15 | ws.onmessage = ({ data }) => { 16 | const JSONdata = JSON.parse(data); 17 | 18 | if (JSONdata.op == OPCODES.HELLO) { 19 | ws.send( 20 | JSON.stringify({ 21 | op: OPCODES.INIT, 22 | d: { 23 | subscribe_to_id: "539843855567028227", 24 | }, 25 | }) 26 | ); 27 | 28 | setInterval(function () { 29 | ws.send( 30 | JSON.stringify({ 31 | op: OPCODES.HEARTBEAT, 32 | }) 33 | ); 34 | }, JSONdata.d.heartbeat_interval); 35 | } else if (JSONdata.op == OPCODES.INFO) { 36 | const getDominantColor = (imgUrl, cb) => { 37 | const img = new window.Image(); 38 | img.crossOrigin = "Anonymous"; 39 | img.src = imgUrl; 40 | img.onload = function () { 41 | const canvas = document.createElement("canvas"); 42 | canvas.width = img.width; 43 | canvas.height = img.height; 44 | const ctx = canvas.getContext("2d"); 45 | ctx.drawImage(img, 0, 0); 46 | const data = ctx.getImageData(0, 0, canvas.width, canvas.height).data; 47 | let r = 0, g = 0, b = 0, count = 0; 48 | for (let i = 0; i < data.length; i += 4) { 49 | r += data[i]; 50 | g += data[i + 1]; 51 | b += data[i + 2]; 52 | count++; 53 | } 54 | r = Math.round(r / count); 55 | g = Math.round(g / count); 56 | b = Math.round(b / count); 57 | cb([r, g, b]); 58 | }; 59 | img.onerror = function () { 60 | cb([0, 0, 0]); 61 | }; 62 | }; 63 | 64 | const getAlertClassByColor = ([r, g, b]) => { 65 | const max = Math.max(r, g, b); 66 | const min = Math.min(r, g, b); 67 | const isWhite = max > 230 && min > 200; 68 | const isBlack = max < 40 && min < 40; 69 | if (isWhite) return "alert-outline"; 70 | if (isBlack) return "alert-neutral"; 71 | // HSV'ye çevir 72 | const rr = r / 255, gg = g / 255, bb = b / 255; 73 | const mx = Math.max(rr, gg, bb), mn = Math.min(rr, gg, bb); 74 | const d = mx - mn; 75 | let h = 0; 76 | if (d === 0) h = 0; 77 | else if (mx === rr) h = ((gg - bb) / d) % 6; 78 | else if (mx === gg) h = (bb - rr) / d + 2; 79 | else h = (rr - gg) / d + 4; 80 | h = Math.round(h * 60); 81 | if (h < 0) h += 360; 82 | 83 | // En yakın renk grubu 84 | if (h >= 60 && h < 160) return "alert-success"; //Yeşil tonları 85 | if (h >= 160 && h < 250) return "alert-info"; //Mavi Tonları 86 | if ((h >= 0 && h < 20) || (h >= 340 && h <= 360)) return "alert-error"; // Kırmızı/Pembe Tonları 87 | if (h >= 20 && h < 60) return "alert-warning";// Sarı/Turuncu Tonları 88 | if (h >= 250 && h < 300) return "alert-accent"; //Mor Tonları 89 | if (h >= 300 && h < 340) return "alert-accent"; //Eflatun Tonları 90 | return "alert-neutral"; 91 | }; 92 | 93 | const updateSpotifyUI = (u) => { 94 | if (u.listening_to_spotify) { 95 | document 96 | .getElementById("spotifycheck") 97 | .classList.replace("hidden", "visible"); 98 | 99 | const albumArtUrl = u.spotify.album_art_url; 100 | document.getElementById("albumart").src = albumArtUrl; 101 | document.getElementById("albumname")?.setAttribute("data-tip", u.spotify.album); 102 | document.getElementById("title").innerText = u.spotify.song; 103 | document.getElementById("artist").innerText = u.spotify.artist; 104 | 105 | // Şarkı ilerlemesini ilet 106 | if (u.spotify.timestamps?.start && u.spotify.timestamps?.end) { 107 | const event = new CustomEvent("spotify-progress", { 108 | detail: { 109 | start: u.spotify.timestamps.start, 110 | end: u.spotify.timestamps.end, 111 | isPlaying: true 112 | } 113 | }); 114 | window.dispatchEvent(event); 115 | } else { 116 | // Şarkı yoksa ilerlemeyi sıfırla 117 | const event = new CustomEvent("spotify-progress", { 118 | detail: { 119 | start: 0, 120 | end: 0, 121 | isPlaying: false 122 | } 123 | }); 124 | window.dispatchEvent(event); 125 | } 126 | 127 | // Alert class güncelle 128 | getDominantColor(albumArtUrl, (rgb) => { 129 | const alertDiv = document.getElementById("alertDiv"); 130 | if (alertDiv) { 131 | alertDiv.classList.remove( 132 | "alert-success", 133 | "alert-info", 134 | "alert-error", 135 | "alert-warning", 136 | "alert-neutral", 137 | "alert-outline" 138 | ); 139 | const newClass = getAlertClassByColor(rgb); 140 | if (newClass) alertDiv.classList.add(newClass); 141 | } 142 | }); 143 | } else { 144 | // Spotify dinlenmiyorsa ilerlemeyi sıfırla 145 | const event = new CustomEvent("spotify-progress", { 146 | detail: { 147 | start: 0, 148 | end: 0, 149 | isPlaying: false 150 | } 151 | }); 152 | window.dispatchEvent(event); 153 | } 154 | }; 155 | 156 | if (JSONdata.t == "INIT_STATE") { 157 | //first 158 | const u = JSONdata.d; //userdata 159 | document.getElementById( 160 | "avatar" 161 | ).src = `https://cdn.discordapp.com/avatars/539843855567028227/${u.discord_user.avatar}.png?size=4096`; 162 | updateSpotifyUI(u); 163 | } else if (JSONdata.t == "PRESENCE_UPDATE") { 164 | //update 165 | const u = JSONdata.d; 166 | document.getElementById( 167 | "avatar" 168 | ).src = `https://cdn.discordapp.com/avatars/539843855567028227/${u.discord_user.avatar}.png?size=4096`; 169 | updateSpotifyUI(u); 170 | } 171 | } 172 | }; //onmessage 173 | } 174 | }); 175 | }); -------------------------------------------------------------------------------- /pages/anilist.vue: -------------------------------------------------------------------------------- 1 | 111 | 241 | 256 | --------------------------------------------------------------------------------