Saya membina PeerSplit—alternatif peer-to-peer percuma kepada Splitwise—dalam masa dua minggu sahaja, dari idea hingga pelancaran!
PeerSplit ialah apl tempatan pertama untuk memisahkan perbelanjaan kumpulan. Ia berfungsi di luar talian, 100% percuma dan peribadi serta tidak memerlukan pendaftaran atau sebarang data peribadi.
Begini cara saya membinanya dan semua yang saya pelajari sepanjang perjalanan.
Saya telah bergantung pada Splitwise selama bertahun-tahun untuk menguruskan perbelanjaan dengan rakan dan rakan sebilik. Tetapi dengan had transaksi harian terkini dan iklan yang mengganggu, ia menjadi mengecewakan untuk digunakan.
Saya mahukan alternatif percuma yang mengutamakan privasi yang tidak memerlukan pelayan untuk menyimpan atau menyegerakkan data. Saya tidak akan mempercayai perbelanjaan saya dengan pelayan pihak ketiga.
Selepas mengusahakan projek peer-to-peer, local-first seperti penjejak senaman dan apl penulisan tanpa gangguan, saya menyedari bahawa saya boleh menggunakan pendekatan yang sama untuk pembahagian perbelanjaan.
Begitulah cara PeerSplit dilahirkan. Saya mula mereka bentuk apl.
Saya malas mereka bentuk UI.
Beberapa bulan yang lalu, saya tidak sangka saya boleh membina UI sebaik PeerSplit (sesetengah orang mengatakan ia mempunyai UX yang lebih baik daripada Splitwise).
Jadi, bagaimana saya berjaya melakukannya? UI Nuxt.
UI Nuxt sangat cantik dan mempunyai pengalaman pembangun (DX) yang menakjubkan.
Ia turut disertakan dengan modul Nuxt lain yang berguna seperti @nuxt/icon, @nuxtjs/tailwindcss dan @nuxtjs/colormode.
Apa yang saya perlu lakukan ialah memilih warna utama dan saya mempunyai semua komponen yang saya perlukan—ikon, mod gelap dan segala-galanya—untuk menggabungkan UI PeerSplit.
Untuk penyimpanan dan penyegerakan data setempat, saya menggunakan cr-sqlite, yang dibina pada wa-sqlite dan menggunakan CRDT (jenis data replika tanpa konflik).
CRDT bagus untuk sistem peer-to-peer kerana ia mengendalikan konflik secara automatik—jadi pengguna boleh bekerja di luar talian dan apabila mereka menyambung semula, perubahan bergabung dengan lancar.
Walau bagaimanapun, cr-sqlite tidak menyegerakkan perubahan melalui rangkaian dengan sendirinya. Ia hanya menyediakan API untuk mengeksport dan menggabungkan perubahan. Anda perlu menghantar perubahan tersebut secara manual antara peranti.
Untuk mengendalikan penyegerakan peer-to-peer yang selamat, saya menggunakan Gun.js, yang menyediakan pangkalan data graf teragih rakan-ke-rakan.
API gun.user Gun membenarkan saya membuat nod yang disulitkan untuk setiap kumpulan. Semua perubahan untuk kumpulan disimpan pada nod itu dan disegerakkan hanya dengan ahli kumpulan, memastikan semuanya tertutup.
Apabila pengguna melakukan tindakan, saya mengambil perubahan yang dieksport daripada cr-sqlite dan menolaknya ke nod. Apabila pengguna kembali dalam talian, Gun menyegerakkan perubahan baharu, memastikan semua orang sentiasa dikemas kini.
Melaksanakan ini dengan cara yang berprestasi adalah rumit. Untuk butiran lanjut, anda boleh menyemak kod sumber di sini.
Satu ciri hebat Splitwise (dan kini PeerSplit) ialah "memudahkan hutang."
Begini cara ia berfungsi: Jika A berhutang dengan B dan B berhutang C, A hanya boleh membayar C terus untuk mengurangkan jumlah pembayaran balik.
Dalam PeerSplit, saya mula-mula mengira baki bersih untuk setiap orang. Kemudian saya mengisih baki tersebut dan mencadangkan pembayaran satu demi satu untuk membawa sekurang-kurangnya baki seorang kepada sifar setiap kali.
Isih ini memastikan semua orang melihat pembayaran balik yang sama pada peranti mereka.
Ia tidak 100% optimum (sesetengah kumpulan mungkin masih mempunyai sehingga n-1 pembayaran), tetapi ia berfungsi dengan baik dalam kebanyakan kes.
Penyelesaian optimum adalah eksponen untuk dikira dan hanya akan menjimatkan beberapa pembayaran. Jadi ini adalah pertukaran terbaik untuk kesederhanaan dan kepantasan!
export const groupGetPayments = (group) => { const payments = []; const balances = Object.entries(groupGetBalances(group)).map(([a, b]) => [ b, a, ]); balances.sort(); let i = 0, j = balances.length - 1; while (i < j) { if (balances[i][0] === 0) { i++; } else if (balances[j][0] === 0) { j--; } else if (-balances[i][0] > balances[j][0]) { payments.push({ from: balances[i][1], to: balances[j][1], value: round(balances[j][0]), }); balances[i][0] += balances[j][0]; balances[j][0] = 0; } else { payments.push({ from: balances[i][1], to: balances[j][1], value: round(-balances[i][0]), }); balances[j][0] += balances[i][0]; balances[i][0] = 0; } } return payments; };
Saya mahu PeerSplit berfungsi sebagai apl luar talian, tetapi saya tidak mahu bersusah payah membina berbilang aplikasi asli atau menangani proses yang panjang untuk menerbitkannya di gedung aplikasi. Jadi, memilih Apl Web Progresif (PWA) ialah pilihan yang jelas.
PWA menggabungkan aplikasi web dan mudah alih yang terbaik, membolehkan pengguna memasangnya pada peranti mereka sambil masih menikmati keupayaan luar talian.
Untuk menukar apl Nuxt saya kepada PWA, saya menggunakan vite-pwa.
Saya mereka logo SVG dalam Figma dan menggunakannya untuk menjana semua aset PWA yang diperlukan melalui penjana aset vite-pwa.
Selepas itu, saya mengkonfigurasi manifes PWA dan vite-pwa secara automatik menyediakan pekerja perkhidmatan untuk saya.
Saya mengkonfigurasi Nuxt untuk prapaparan semua laluan, supaya apl saya boleh berfungsi sepenuhnya di luar talian.
Dan itu pembalut. Terima kasih kerana membaca!
PeerSplit baru sahaja dilancarkan pada Product Hunt! Ini adalah pelancaran pertama saya, dan saya suka sokongan dan maklum balas anda.
Lihat PeerSplit pada Product Hunt
PeerSplit ialah sumber yang adil, jadi jangan ragu untuk menyumbang atau menyerahkan permintaan ciri di GitHub.
PeerSplit ialah apl peer-to-peer percuma, diutamakan tempatan, yang membantu anda memisahkan dan menjejaki perbelanjaan kumpulan dengan mudah dan persendirian.
Atas ialah kandungan terperinci Cara saya membina PeerSplit: Apl pembahagi perbelanjaan rakan-ke-rakan percuma—daripada idea untuk dilancarkan dalam beberapa minit sahaja. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!