lnbits paid articles added

This commit is contained in:
HolgerHatGarKeineNode
2023-03-13 16:35:20 +01:00
parent 9f51c71439
commit 639e17080c
30 changed files with 838 additions and 60 deletions

View File

@@ -820,6 +820,25 @@
"sats": "sats",
"Your vote": "Deine Stimme",
"Association": "Verein",
"for voting you have to be logged in": "",
"Yes, support it!": "Ja, unterstützen!"
"for voting you have to be logged in": "für die Abstimmung musst du angemeldet sein",
"Yes, support it!": "Ja, unterstützen!",
"LNBits settings saved successfully!": "LNBits-Einstellungen erfolgreich gespeichert!",
"LNBits": "",
"Submit paid news article": "Reiche einen bezahlten News-Artikel ein",
"Paid article": "Bezahlter Artikel",
"Paid News Article": "Bezahlter News-Artikel",
"How many sats to read this article?": "Wie viele sats für den Zugriff auf diesen Artikel?",
"Free part of the Article as Markdown": "Kostenloser Teil des Artikels als Markdown",
"Part of the article to be paid": "Zu zahlender Teil des Artikels",
"You can read the full article if you paid with Lightning": "Du kannst den vollständigen Artikel lesen, wenn du mit Lightning bezahlt hast",
"Receiver": "Empfänger",
"already paid?": "schon bezahlt?",
"Payment Hash": "Payment Hash",
"Payment hash copied!": "Payment Hash kopiert!",
"Copy payment hash": "Kopiere Payment Hash",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "Gib hier die Daten deiner LNBits-Instanz ein, um sats für zum Beispiel Artikel zu erhalten.",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": "zu bezahlen"
}

View File

@@ -818,5 +818,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -818,5 +818,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -819,5 +819,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -819,5 +819,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -819,5 +819,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -819,5 +819,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -819,5 +819,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -819,5 +819,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -781,5 +781,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -793,5 +793,25 @@
"Your vote": "",
"Association": "",
"for voting you have to be logged in": "",
"Yes, support it!": ""
"Yes, support it!": "",
"LNBits settings saved successfully!": "",
"LNBits": "",
"Submit paid news article": "",
"Paid article": "",
"Paid News Article": "",
"Sats": "",
"How many sats to read this article?": "",
"Free part of the Article as Markdown": "",
"Part of the article to be paid": "",
"You can read the full article if you paid with Lightning": "",
"Receiver": "",
"already paid?": "",
"Payment Hash": "",
"Payment hash copied!": "",
"Copy payment hash": "",
"Enter the data of your LNBits instance here to receive sats for articles, for example.": "",
"LNBits Url": "",
"Wallet ID": "",
"Invoice\/read key": "",
"paid": ""
}

View File

@@ -42,6 +42,12 @@
{{ __('My meetups') }}
</a>
<a href="{{ route('profile.lnbits') }}"
class="flex gap-x-4 py-2 text-sm font-semibold leading-6 text-gray-900">
<i class="fa-thin fa-key-skeleton-left-right flex-none text-gray-400"></i>
{{ __('LNBits') }}
</a>
</div>
</div>
</div>

View File

@@ -15,11 +15,22 @@
<div>
@auth
<x-button
class="whitespace-nowrap"
:href="route('news.form')"
primary>
<i class="fa fa-thin fa-plus"></i>
{{ __('Submit news articles') }}
</x-button>
@if(auth()->user()->lnbits)
<x-button
class="whitespace-nowrap"
:href="route('news.form', ['paid' => true])"
primary>
<i class="fa fa-thin fa-plus"></i>
{{ __('Submit paid news article') }}
<i class="fa fa-thin fa-coins"></i>
</x-button>
@endif
@endauth
</div>
</div>
@@ -28,7 +39,15 @@
@foreach($libraryItems as $libraryItem)
@if($libraryItem->approved || $libraryItem->created_by === auth()->id() || auth()->user()?->hasRole('news-editor'))
<div wire:key="library_item_{{ $libraryItem->id }}" wire:loading.class="opacity-25"
class="flex flex-col overflow-hidden rounded-lg border-2 border-[#F7931A]">
class="relative flex flex-col overflow-hidden rounded-lg border-2 border-[#F7931A]">
@if($libraryItem->sats)
<div class="absolute -left-1 top-0 h-16 w-16">
<div
class="absolute transform -rotate-45 bg-amber-500 text-center text-white font-semibold py-1 left-[-34px] top-[32px] w-[170px]">
{{ __('paid') }}
</div>
</div>
@endif
<div class="flex-shrink-0 pt-6">
<a href="{{ route('article.view', ['libraryItem' => $libraryItem]) }}">
<img class="h-48 w-full object-contain"

View File

@@ -5,7 +5,11 @@
<div class="container p-4 mx-auto bg-21gray my-2">
<div class="pb-5 flex flex-row justify-between">
<h3 class="text-lg font-medium leading-6 text-gray-200">{{ __('News Article') }}</h3>
@if($paid)
<h3 class="text-lg font-medium leading-6 text-gray-200">{{ __('Paid News Article') }}</h3>
@else
<h3 class="text-lg font-medium leading-6 text-gray-200">{{ __('News Article') }}</h3>
@endif
<div class="flex flex-row space-x-2 items-center justify-between">
<div x-data="{}">
@if($libraryItem->created_by === auth()->id())
@@ -36,6 +40,13 @@
<div class="space-y-8 divide-y divide-gray-700 sm:space-y-5">
<div class="mt-6 sm:mt-5 space-y-6 sm:space-y-5">
@if($paid)
<x-input.group :for="md5('libraryItem.sats')" :label="__('sats')">
<x-inputs.number min="21" autocomplete="off" wire:model.debounce="libraryItem.sats"
:placeholder="__('sats')" :hint="__('How many sats to read this article?')"/>
</x-input.group>
@endif
<x-input.group :for="md5('libraryItem.lecturer_id')">
<x-slot name="label">
<div class="flex flex-row space-x-4 items-center">
@@ -113,13 +124,22 @@
/>
</x-input.group>
<x-input.group :for="md5('libraryItem.value')" :label="__('Article as Markdown')">
<x-input.group :for="md5('libraryItem.value')" :label="$paid ? __('Free part of the Article as Markdown') : __('Article as Markdown')">
<div
class="text-amber-500 text-xs py-2">{{ __('For images in Markdown, please use eg. Imgur or another provider.') }}</div>
<x-input.simple-mde wire:model.defer="libraryItem.value"/>
@error('libraryItem.value') <span class="text-red-500 py-2">{{ $message }}</span> @enderror
</x-input.group>
@if($paid)
<x-input.group :for="md5('libraryItem.value_to_be_paid')" :label="__('Part of the article to be paid')">
<div
class="text-amber-500 text-xs py-2">{{ __('For images in Markdown, please use eg. Imgur or another provider.') }}</div>
<x-input.simple-mde wire:model.defer="libraryItem.value_to_be_paid"/>
@error('libraryItem.value_to_be_paid') <span class="text-red-500 py-2">{{ $message }}</span> @enderror
</x-input.group>
@endif
<x-input.group :for="md5('libraryItem.read_time')" :label="__('Time to read')">
<x-inputs.number min="1" autocomplete="off" wire:model.debounce="libraryItem.read_time"
:placeholder="__('Time to read')" :hint="__('How many minutes to read?')"/>

View File

@@ -138,7 +138,127 @@
{!! $libraryItem->value !!}
</x-markdown>
@endif
</div>
@if($libraryItem->sats && !$invoicePaid)
<div
class="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div
class="relative isolate overflow-hidden bg-gray-900 px-6 py-12 text-center shadow-2xl sm:rounded-3xl sm:px-16">
<h2 class="mx-auto max-w-2xl text-3xl font-bold tracking-tight text-white sm:text-4xl">
{{ __('You can read the full article if you paid with Lightning') }}
</h2>
<div
class="flex max-w-2xl text-3xl font-bold tracking-tight text-white sm:text-4xl justify-center items-center">
<div class="mt-6 flex items-center">
<div class="flex-shrink-0">
<div>
<span
class="sr-only text-gray-200">{{ $libraryItem->lecturer->name }}</span>
<img class="h-10 w-10 object-cover rounded"
src="{{ $libraryItem->lecturer->getFirstMediaUrl('avatar') }}"
alt="{{ $libraryItem->lecturer->name }}">
</div>
</div>
<div class="ml-3">
<div class="text-sm font-medium text-gray-200">
<div class="text-gray-200">{{ __('Receiver') }}
: {{ $libraryItem->lecturer->name }}</div>
</div>
<div class="flex space-x-1 text-sm text-gray-300">
<time
datetime="2020-03-16">{{ number_format($libraryItem->sats, 0, ',', '.') }} {{ __('sats') }}</time>
</div>
</div>
</div>
</div>
@if(!$invoice)
<div class="mt-10 flex items-center justify-center gap-x-6">
<div
wire:click="pay"
class="cursor-pointer rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-sm hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white">
<i class="fa-thin fa-bolt"></i>
Pay with lightning
</div>
<div wire:click="$set('alreadyPaid', true)" class="cursor-pointer text-sm font-semibold leading-6 text-white">{{ __('already paid?') }} <span aria-hidden="true"></span></div>
</div>
@else
<div class="mt-10 flex items-center justify-center gap-x-6 bg-white py-12">
<div class="flex justify-center" wire:key="qrcode">
<a href="lightning:{{ $this->invoice }}">
<img src="{{ 'data:image/png;base64, '. $this->qrCode }}" alt="qrcode">
</a>
</div>
</div>
@endif
@if(!$invoice)
<svg viewBox="0 0 1024 1024"
class="absolute top-1/2 left-1/2 -z-10 h-[64rem] w-[64rem] -translate-x-1/2 [mask-image:radial-gradient(closest-side,white,transparent)]"
aria-hidden="true">
<circle cx="512" cy="512" r="512"
fill="url(#827591b1-ce8c-4110-b064-7cb85a0b1217)" fill-opacity="0.7"/>
<defs>
<radialGradient id="827591b1-ce8c-4110-b064-7cb85a0b1217">
<stop stop-color="#F7931A"/>
<stop offset="1" stop-color="#F7931A"/>
</radialGradient>
</defs>
</svg>
@endif
@if($alreadyPaid)
<div class="flex items-center justify-center gap-x-6 py-2">
<div class="w-full flex flex-col space-y-2 justify-center" wire:key="paymentHash">
<div class="w-full my-2 flex justify-center font-mono break-all py-2">
<x-input.group :for="md5('checkThisPaymentHash')" :label="__('Payment Hash')">
<x-input autocomplete="off" wire:model.debounce="checkThisPaymentHash"
:placeholder="__('Payment Hash')"/>
</x-input.group>
</div>
</div>
@if($checkThisPaymentHash)
<div wire:poll.keep-alive="checkPaymentHash" wire:key="checkPaymentHash"></div>
@endif
</div>
@endif
@if($invoice)
<div class="flex items-center justify-center gap-x-6 bg-white py-2">
<div class="w-full flex flex-col space-y-2 justify-center" wire:key="paymentHash">
<div class="w-full my-2 flex justify-center font-mono break-all py-2">
<input class="w-full" readonly wire:key="paymentHashInput"
onClick="this.select();"
value="{{ $this->paymentHash }}"/>
</div>
<div
x-data="{
textToCopy: '{{ $this->paymentHash }}',
}"
@click.prevent="window.navigator.clipboard.writeText(textToCopy);window.$wireui.notify({title:'{{ __('Payment hash copied!') }}',icon:'success'});"
>
<x-button
black
>
<i class="fa fa-thin fa-clipboard"></i>
{{ __('Copy payment hash') }}
</x-button>
</div>
</div>
<div wire:poll.keep-alive="checkPaymentHash" wire:key="checkPaymentHash"></div>
</div>
@endif
</div>
</div>
@else
<div
class="prose md:prose-lg prose-invert mx-auto mt-5 text-gray-100 lg:col-start-1 lg:row-start-1 lg:max-w-none">
<x-markdown class="leading-normal">
{!! $libraryItem->value_to_be_paid !!}
</x-markdown>
</div>
@endif
<div wire:ignore>
<div class="flex flex-col sm:flex-row justify-center space-x-4 border-t border-white py-4 mt-4">
@if($libraryItem->lecturer->lightning_address || $libraryItem->lecturer->lnurl || $libraryItem->lecturer->node_id)
<h1>value-4-value</h1>
@@ -163,7 +283,14 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
<div x-data="{paid: @entangle('invoicePaid')}" x-init="$watch('paid', value => {if (value) {
party.confetti(document.body, {
count: party.variation.range(20, 40),
});
}})"></div>
<div wire:ignore class="z-50">
<script src="https://cdn.jsdelivr.net/npm/party-js@latest/bundle/party.min.js"></script>
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
data-website-owner-pubkey="daf83d92768b5d0005373f83e30d4203c0b747c170449e02fea611a0da125ee6"

View File

@@ -0,0 +1,53 @@
<div>
{{-- HEADER --}}
<livewire:frontend.header :country="null"/>
<div class="flex flex-col">
<section class="">
<div class="px-10 pt-6 mx-auto max-w-7xl">
<div class="w-full mx-auto text-left md:text-center">
<h1 class="mb-6 text-5xl font-extrabold leading-none max-w-5xl mx-auto tracking-normal text-gray-900 sm:text-6xl md:text-6xl lg:text-7xl md:tracking-tight">
<span
class="w-full text-transparent bg-clip-text bg-gradient-to-r from-amber-400 via-amber-500 to-amber-500 lg:inline">{{ __('LNBits') }}</span>
</h1>
<p class="px-0 mb-6 text-lg text-gray-200 md:text-xl lg:px-24">
{{ __('Enter the data of your LNBits instance here to receive sats for articles, for example.') }}
</p>
</div>
</div>
</section>
<div class="container p-4 mx-auto bg-21gray my-2">
<form class="space-y-8 divide-y divide-gray-700 pb-24">
<div class="space-y-8 divide-y divide-gray-700 sm:space-y-5">
<div class="mt-6 sm:mt-5 space-y-6 sm:space-y-5">
<x-input.group :for="md5('settings.url')" :label="__('LNBits Url')">
<x-input autocomplete="off" wire:model.debounce="settings.url"
:placeholder="__('LNBits Url')"/>
</x-input.group>
<x-input.group :for="md5('settings.wallet_id')" :label="__('Wallet ID')">
<x-input autocomplete="off" wire:model.debounce="settings.wallet_id"
:placeholder="__('Wallet ID')"/>
</x-input.group>
<x-input.group :for="md5('settings.read_key')" :label="__('Invoice/read key')">
<x-input autocomplete="off" wire:model.debounce="settings.read_key"
:placeholder="__('Invoice/read key')"/>
</x-input.group>
<x-input.group :for="md5('save')" label="">
<x-button primary wire:click="save">
<i class="fa fa-thin fa-save"></i>
{{ __('Save') }}
</x-button>
</x-input.group>
</div>
</div>
</form>
</div>
</div>
</div>