8f590425dc
* Add icon to add images * Open file explorer to select image * Upload images to S3 on selection * Show uploaded images below text input * Link and remove image * Fetch unsubmitted images from database * Mark S3 images as submitted in imgproxy job * Add margin-top * Mark images as submitted on client after successful mutation * Also delete objects in S3 * Allow items to have multiple uploads linked * Overwrite old avatar * Add fees for presigned URLs * Use Github style upload * removed upfront fees * removed images provider since we no longer need to keep track of unsubmitted images on the client * removed User.images resolver * removed deleteImage mutation * use Github style upload where it shows ![Uploading <filename>...]() first and then replaces that with ![<filename>](<url>) after successful upload * Add Upload.paid boolean column One item can have multiple images linked to it, but an image can also be used in multiple items (many-to-many relation). Since we don't really care to which item an image is linked and vice versa, we just use a boolean column to mark if an image was already paid for. This makes fee calculation easier since no JOINs are required. * Add image fees during item creation/update * we calculate image fees during item creation and update now * function imageFees returns queries which deduct fees from user and mark images as paid + fees * queries need to be run inside same transaction as item creation/update * Allow anons to get presigned URLs * Add comments regarding avatar upload * Use megabytes in error message * Remove unnecessary avatar check during image fees calculation * Show image fees in frontend * Also update image fees on blur This makes sure that the images fees reflect the current state. For example, if an image was removed. We could also add debounced requests. * Show amount of unpaid images in receipt * Fix fees in sats deducted from msats * Fix algebraic order of fees Spam fees must come immediately after the base fee since it multiplies the base fee. * Fix image fees in edit receipt * Fix stale fees shown If we pay for an image and then want to edit the comment, the cache might return stale date; suggesting we didn't pay for the existing image yet. * Add 0 base fee in edit receipt * Remove 's' from 'image fees' in receipts * Remove unnecessary async * Remove 'Uploading <name>...' from text input on error * Support upload of multiple files at once * Add schedule to delete unused images * Fix image fee display in receipts * Use Drag and Drop API for image upload * Remove dragOver style on drop * Increase max upload size to 10MB to allow HQ camera pictures * Fix free upload quota * Fix stale image fees served * Fix bad image fee return statements * Fix multiplication with feesPerImage * Fix NULL returned for size24h, sizeNow * Remove unnecessary text field in query * refactor: Unify <ImageUpload> and <Upload> component * Add avatar cache busting using random query param * Calculate image fee info in postgres function * we now calculate image fee info in a postgres function which is much cleaner * we use this function inside `create_item` and `update_item`: image fees are now deducted in the same transaction as creating/updating the item! * reversed changes in `serializeInvoiceable` * Fix line break in receipt * Update upload limits * Add comment about `e.target.value = null` * Use debounce instead of onBlur to update image fees info * Fix invoice amount * Refactor avatar upload control flow * Update image fees in onChange * Fix rescheduling of other jobs * also update schedule from every minute to every hour * Add image fees in calling context * keep item ids on uploads * Fix incompatible onSubmit signature * Revert "keep item ids on uploads" This reverts commit 4688962abcd54fdc5850109372a7ad054cf9b2e4. * many2many item uploads * pretty subdomain for images * handle upload conditions for profile images and job logos --------- Co-authored-by: ekzyis <ek@ekzyis.com> Co-authored-by: ekzyis <ek@stacker.news>
80 lines
2.5 KiB
JavaScript
80 lines
2.5 KiB
JavaScript
import PgBoss from 'pg-boss'
|
|
import nextEnv from '@next/env'
|
|
import { PrismaClient } from '@prisma/client'
|
|
import { checkInvoice, checkWithdrawal } from './wallet.js'
|
|
import { repin } from './repin.js'
|
|
import { trust } from './trust.js'
|
|
import { auction } from './auction.js'
|
|
import { earn } from './earn.js'
|
|
import apolloClient from '@apollo/client'
|
|
import { indexItem, indexAllItems } from './search.js'
|
|
import { timestampItem } from './ots.js'
|
|
import { computeStreaks, checkStreak } from './streak.js'
|
|
import { nip57 } from './nostr.js'
|
|
import fetch from 'cross-fetch'
|
|
import { authenticatedLndGrpc } from 'ln-service'
|
|
import { views, rankViews } from './views.js'
|
|
import { imgproxy } from './imgproxy.js'
|
|
import { deleteItem } from './ephemeralItems.js'
|
|
import { deleteUnusedImages } from './deleteUnusedImages.js'
|
|
|
|
const { loadEnvConfig } = nextEnv
|
|
const { ApolloClient, HttpLink, InMemoryCache } = apolloClient
|
|
|
|
loadEnvConfig('..')
|
|
|
|
async function work () {
|
|
const boss = new PgBoss(process.env.DATABASE_URL)
|
|
const models = new PrismaClient()
|
|
const apollo = new ApolloClient({
|
|
link: new HttpLink({
|
|
uri: `${process.env.SELF_URL}/api/graphql`,
|
|
fetch
|
|
}),
|
|
cache: new InMemoryCache(),
|
|
defaultOptions: {
|
|
watchQuery: {
|
|
fetchPolicy: 'no-cache',
|
|
nextFetchPolicy: 'no-cache'
|
|
},
|
|
query: {
|
|
fetchPolicy: 'no-cache',
|
|
nextFetchPolicy: 'no-cache'
|
|
}
|
|
}
|
|
})
|
|
|
|
const { lnd } = authenticatedLndGrpc({
|
|
cert: process.env.LND_CERT,
|
|
macaroon: process.env.LND_MACAROON,
|
|
socket: process.env.LND_SOCKET
|
|
})
|
|
|
|
const args = { boss, models, apollo, lnd }
|
|
|
|
boss.on('error', error => console.error(error))
|
|
|
|
await boss.start()
|
|
await boss.work('checkInvoice', checkInvoice(args))
|
|
await boss.work('checkWithdrawal', checkWithdrawal(args))
|
|
await boss.work('repin-*', repin(args))
|
|
await boss.work('trust', trust(args))
|
|
await boss.work('timestampItem', timestampItem(args))
|
|
await boss.work('indexItem', indexItem(args))
|
|
await boss.work('indexAllItems', indexAllItems(args))
|
|
await boss.work('auction', auction(args))
|
|
await boss.work('earn', earn(args))
|
|
await boss.work('streak', computeStreaks(args))
|
|
await boss.work('checkStreak', checkStreak(args))
|
|
await boss.work('nip57', nip57(args))
|
|
await boss.work('views', views(args))
|
|
await boss.work('rankViews', rankViews(args))
|
|
await boss.work('imgproxy', imgproxy(args))
|
|
await boss.work('deleteItem', deleteItem(args))
|
|
await boss.work('deleteUnusedImages', deleteUnusedImages(args))
|
|
|
|
console.log('working jobs')
|
|
}
|
|
|
|
work()
|