feat: show badge if an extension has paid releases (#3385)
Co-authored-by: dni ⚡ <office@dnilabs.com>
This commit is contained in:
parent
015262c9b3
commit
f48d24aca8
6 changed files with 88 additions and 16 deletions
|
|
@ -39,6 +39,7 @@ class ExplicitRelease(BaseModel):
|
||||||
info_notification: str | None
|
info_notification: str | None
|
||||||
critical_notification: str | None
|
critical_notification: str | None
|
||||||
details_link: str | None
|
details_link: str | None
|
||||||
|
paid_features: str | None
|
||||||
pay_link: str | None
|
pay_link: str | None
|
||||||
|
|
||||||
def is_version_compatible(self):
|
def is_version_compatible(self):
|
||||||
|
|
@ -187,6 +188,7 @@ class ExtensionRelease(BaseModel):
|
||||||
icon: str | None = None
|
icon: str | None = None
|
||||||
details_link: str | None = None
|
details_link: str | None = None
|
||||||
|
|
||||||
|
paid_features: str | None = None
|
||||||
pay_link: str | None = None
|
pay_link: str | None = None
|
||||||
cost_sats: int | None = None
|
cost_sats: int | None = None
|
||||||
paid_sats: int | None = 0
|
paid_sats: int | None = 0
|
||||||
|
|
@ -256,6 +258,7 @@ class ExtensionRelease(BaseModel):
|
||||||
html_url=e.html_url,
|
html_url=e.html_url,
|
||||||
details_link=e.details_link,
|
details_link=e.details_link,
|
||||||
pay_link=e.pay_link,
|
pay_link=e.pay_link,
|
||||||
|
paid_features=e.paid_features,
|
||||||
repo=e.repo,
|
repo=e.repo,
|
||||||
icon=e.icon,
|
icon=e.icon,
|
||||||
)
|
)
|
||||||
|
|
@ -308,6 +311,9 @@ class ExtensionMeta(BaseModel):
|
||||||
dependencies: list[str] = []
|
dependencies: list[str] = []
|
||||||
archive: str | None = None
|
archive: str | None = None
|
||||||
featured: bool = False
|
featured: bool = False
|
||||||
|
paid_features: str | None = None
|
||||||
|
has_paid_release: bool = False
|
||||||
|
has_free_release: bool = False
|
||||||
|
|
||||||
|
|
||||||
class InstallableExtension(BaseModel):
|
class InstallableExtension(BaseModel):
|
||||||
|
|
@ -451,9 +457,23 @@ class InstallableExtension(BaseModel):
|
||||||
|
|
||||||
shutil.rmtree(self.ext_upgrade_dir, True)
|
shutil.rmtree(self.ext_upgrade_dir, True)
|
||||||
|
|
||||||
def check_latest_version(self, release: ExtensionRelease | None):
|
def check_release_updates(self, release: ExtensionRelease | None):
|
||||||
|
self._check_latest_version(release)
|
||||||
|
self._check_payment_link(release)
|
||||||
|
|
||||||
|
def find_existing_payment(self, pay_link: str | None) -> ReleasePaymentInfo | None:
|
||||||
|
if not pay_link or not self.meta or not self.meta.payments:
|
||||||
|
return None
|
||||||
|
return next(
|
||||||
|
(p for p in self.meta.payments if p.pay_link == pay_link),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _check_latest_version(self, release: ExtensionRelease | None):
|
||||||
if not release:
|
if not release:
|
||||||
return
|
return
|
||||||
|
if not release.is_version_compatible:
|
||||||
|
return
|
||||||
if not self.meta or not self.meta.latest_release:
|
if not self.meta or not self.meta.latest_release:
|
||||||
meta = self.meta or ExtensionMeta()
|
meta = self.meta or ExtensionMeta()
|
||||||
meta.latest_release = release
|
meta.latest_release = release
|
||||||
|
|
@ -464,13 +484,25 @@ class InstallableExtension(BaseModel):
|
||||||
):
|
):
|
||||||
self.meta.latest_release = release
|
self.meta.latest_release = release
|
||||||
|
|
||||||
def find_existing_payment(self, pay_link: str | None) -> ReleasePaymentInfo | None:
|
def _check_payment_link(self, release: ExtensionRelease | None):
|
||||||
if not pay_link or not self.meta or not self.meta.payments:
|
if not release:
|
||||||
return None
|
return
|
||||||
return next(
|
if not release.is_version_compatible:
|
||||||
(p for p in self.meta.payments if p.pay_link == pay_link),
|
return
|
||||||
None,
|
if not self.meta:
|
||||||
|
self.meta = ExtensionMeta()
|
||||||
|
if release.pay_link:
|
||||||
|
self.meta.has_paid_release = True
|
||||||
|
else:
|
||||||
|
self.meta.has_free_release = True
|
||||||
|
print(
|
||||||
|
"### release.paid_features",
|
||||||
|
release.name,
|
||||||
|
release.version,
|
||||||
|
release.paid_features,
|
||||||
)
|
)
|
||||||
|
if release.paid_features:
|
||||||
|
self.meta.paid_features = release.paid_features
|
||||||
|
|
||||||
def _restore_payment_info(self):
|
def _restore_payment_info(self):
|
||||||
if (
|
if (
|
||||||
|
|
@ -596,7 +628,7 @@ class InstallableExtension(BaseModel):
|
||||||
(ee for ee in extension_list if ee.id == r.id), None
|
(ee for ee in extension_list if ee.id == r.id), None
|
||||||
)
|
)
|
||||||
if existing_ext and ext.meta:
|
if existing_ext and ext.meta:
|
||||||
existing_ext.check_latest_version(ext.meta.latest_release)
|
existing_ext.check_release_updates(ext.meta.latest_release)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
meta = ext.meta or ExtensionMeta()
|
meta = ext.meta or ExtensionMeta()
|
||||||
|
|
@ -610,10 +642,10 @@ class InstallableExtension(BaseModel):
|
||||||
(ee for ee in extension_list if ee.id == e.id), None
|
(ee for ee in extension_list if ee.id == e.id), None
|
||||||
)
|
)
|
||||||
if existing_ext:
|
if existing_ext:
|
||||||
existing_ext.check_latest_version(release)
|
existing_ext.check_release_updates(release)
|
||||||
continue
|
continue
|
||||||
ext = InstallableExtension.from_explicit_release(e)
|
ext = InstallableExtension.from_explicit_release(e)
|
||||||
ext.check_latest_version(release)
|
ext.check_release_updates(release)
|
||||||
meta = ext.meta or ExtensionMeta()
|
meta = ext.meta or ExtensionMeta()
|
||||||
meta.featured = ext.id in manifest.featured
|
meta.featured = ext.id in manifest.featured
|
||||||
ext.meta = meta
|
ext.meta = meta
|
||||||
|
|
|
||||||
|
|
@ -137,8 +137,40 @@
|
||||||
@click="showExtensionDetails(extension.id, extension.details_link)"
|
@click="showExtensionDetails(extension.id, extension.details_link)"
|
||||||
v-text="extension.name"
|
v-text="extension.name"
|
||||||
></div>
|
></div>
|
||||||
<div>
|
<div style="justify-content: space-between; display: flex">
|
||||||
<lnbits-extension-rating :rating="0" />
|
<lnbits-extension-rating :rating="0" />
|
||||||
|
<q-btn-group size="xs" style="margin: 5px 0">
|
||||||
|
<q-btn
|
||||||
|
v-if="extension.hasFreeRelease"
|
||||||
|
color="green"
|
||||||
|
size="xs"
|
||||||
|
:label="$t('free')"
|
||||||
|
>
|
||||||
|
<q-tooltip>
|
||||||
|
<span v-text="$t('extension_has_free_release')"></span>
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
<q-btn
|
||||||
|
v-if="extension.hasPaidRelease || extension.paidFeatures"
|
||||||
|
color="primary"
|
||||||
|
size="xs"
|
||||||
|
:label="$t('paid')"
|
||||||
|
>
|
||||||
|
<q-tooltip>
|
||||||
|
<span
|
||||||
|
v-if="extension.hasPaidRelease"
|
||||||
|
v-text="$t('extension_has_paid_release')"
|
||||||
|
></span>
|
||||||
|
<br
|
||||||
|
v-if="extension.hasPaidRelease && extension.paidFeatures"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
v-if="extension.paidFeatures"
|
||||||
|
v-text="extension.paidFeatures"
|
||||||
|
></span>
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-btn-group>
|
||||||
</div>
|
</div>
|
||||||
<div style="justify-content: space-between; display: flex">
|
<div style="justify-content: space-between; display: flex">
|
||||||
<q-toggle
|
<q-toggle
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,10 @@ async def api_install_extension(data: CreateExtension):
|
||||||
data.ext_id, data.source_repo, data.archive, data.version
|
data.ext_id, data.source_repo, data.archive, data.version
|
||||||
)
|
)
|
||||||
if not release:
|
if not release:
|
||||||
raise HTTPException(
|
raise HTTPException(HTTPStatus.NOT_FOUND, "Release not found")
|
||||||
status_code=HTTPStatus.NOT_FOUND, detail="Release not found"
|
|
||||||
)
|
if not release.is_version_compatible:
|
||||||
|
raise HTTPException(HTTPStatus.BAD_REQUEST, "Incompatible extension version.")
|
||||||
|
|
||||||
release.payment_hash = data.payment_hash
|
release.payment_hash = data.payment_hash
|
||||||
ext_meta = ExtensionMeta(installed_release=release)
|
ext_meta = ExtensionMeta(installed_release=release)
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,9 @@ async def extensions(request: Request, user: User = Depends(check_user_exists)):
|
||||||
if ext.meta and ext.meta.latest_release
|
if ext.meta and ext.meta.latest_release
|
||||||
else None
|
else None
|
||||||
),
|
),
|
||||||
|
"hasPaidRelease": ext.meta.has_paid_release if ext.meta else False,
|
||||||
|
"hasFreeRelease": ext.meta.has_free_release if ext.meta else False,
|
||||||
|
"paidFeatures": ext.meta.paid_features if ext.meta else False,
|
||||||
"installedRelease": (
|
"installedRelease": (
|
||||||
dict(ext.meta.installed_release)
|
dict(ext.meta.installed_release)
|
||||||
if ext.meta and ext.meta.installed_release
|
if ext.meta and ext.meta.installed_release
|
||||||
|
|
|
||||||
2
lnbits/static/bundle.min.js
vendored
2
lnbits/static/bundle.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -168,6 +168,8 @@ window.localisation.en = {
|
||||||
'Only admin accounts can create extensions',
|
'Only admin accounts can create extensions',
|
||||||
admin_only: 'Admin Only',
|
admin_only: 'Admin Only',
|
||||||
new_version: 'New Version',
|
new_version: 'New Version',
|
||||||
|
extension_has_free_release: 'Has free releases',
|
||||||
|
extension_has_paid_release: 'Has paid releases',
|
||||||
extension_depends_on: 'Depends on:',
|
extension_depends_on: 'Depends on:',
|
||||||
extension_rating_soon: 'Ratings coming soon',
|
extension_rating_soon: 'Ratings coming soon',
|
||||||
extension_installed_version: 'Installed version',
|
extension_installed_version: 'Installed version',
|
||||||
|
|
@ -663,5 +665,7 @@ window.localisation.en = {
|
||||||
callback_success_url_hint:
|
callback_success_url_hint:
|
||||||
'The user will be redirected to this URL after the payment is successful',
|
'The user will be redirected to this URL after the payment is successful',
|
||||||
connected: 'Connected',
|
connected: 'Connected',
|
||||||
not_connected: 'Not Connected'
|
not_connected: 'Not Connected',
|
||||||
|
free: 'Free',
|
||||||
|
paid: 'Paid'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue