[feat] UI for user notifications (#3267)
This commit is contained in:
parent
5e9919c5c5
commit
094a9fc1a1
7 changed files with 142 additions and 6 deletions
|
|
@ -25,6 +25,9 @@ class UserExtra(BaseModel):
|
||||||
first_name: str | None = None
|
first_name: str | None = None
|
||||||
last_name: str | None = None
|
last_name: str | None = None
|
||||||
display_name: str | None = None
|
display_name: str | None = None
|
||||||
|
nostr_notification_identifiers: list[str] = []
|
||||||
|
telegram_chat_id: str | None = None
|
||||||
|
notifications_excluded_wallets: list[str] = []
|
||||||
picture: str | None = None
|
picture: str | None = None
|
||||||
# Auth provider, possible values:
|
# Auth provider, possible values:
|
||||||
# - "env": the user was created automatically by the system
|
# - "env": the user was created automatically by the system
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,11 @@
|
||||||
:label="$t('look_and_feel')"
|
:label="$t('look_and_feel')"
|
||||||
@update="val => tab = val.name"
|
@update="val => tab = val.name"
|
||||||
></q-tab>
|
></q-tab>
|
||||||
|
<q-tab
|
||||||
|
name="notifications"
|
||||||
|
:label="$t('notifications')"
|
||||||
|
@update="val => tab = val.name"
|
||||||
|
></q-tab>
|
||||||
<q-tab
|
<q-tab
|
||||||
name="api_acls"
|
name="api_acls"
|
||||||
:label="$t('access_control_list')"
|
:label="$t('access_control_list')"
|
||||||
|
|
@ -566,6 +571,86 @@
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
|
<q-tab-panel name="notifications">
|
||||||
|
<q-card-section>
|
||||||
|
<div class="row q-mb-md">
|
||||||
|
<div class="col-4">
|
||||||
|
<span
|
||||||
|
v-text="$t('notifications_nostr_identifiers')"
|
||||||
|
></span>
|
||||||
|
</div>
|
||||||
|
<div class="col-8">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model="notifications.nostr.identifier"
|
||||||
|
:hint="$t('notifications_nostr_identifiers_desc')"
|
||||||
|
@keydown.enter="addNostrNotificationIdentifier"
|
||||||
|
>
|
||||||
|
<q-btn
|
||||||
|
@click="addNostrNotificationIdentifier()"
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
icon="add"
|
||||||
|
></q-btn>
|
||||||
|
</q-input>
|
||||||
|
<div>
|
||||||
|
<q-chip
|
||||||
|
v-for="identifier in user.extra.nostr_notification_identifiers"
|
||||||
|
:key="identifier"
|
||||||
|
removable
|
||||||
|
@remove="removeNostrNotificationIdentifier(identifier)"
|
||||||
|
color="primary"
|
||||||
|
text-color="white"
|
||||||
|
><span class="ellipsis" v-text="identifier"></span
|
||||||
|
></q-chip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row q-mb-md">
|
||||||
|
<div class="col-4">
|
||||||
|
<span v-text="$t('notifications_chat_id')"></span>
|
||||||
|
</div>
|
||||||
|
<div class="col-8">
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-model="user.extra.telegram_chat_id"
|
||||||
|
:hint="$t('notifications_chat_id_desc')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row q-mb-md">
|
||||||
|
<div class="col-4">
|
||||||
|
<span v-text="$t('exclude_wallets')"></span>
|
||||||
|
</div>
|
||||||
|
<div class="col-8">
|
||||||
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
multiple
|
||||||
|
v-model="user.extra.notifications_excluded_wallets"
|
||||||
|
:options="g.user.walletOptions"
|
||||||
|
:label="$t('exclude_wallets')"
|
||||||
|
:hint="$t('notifications_excluded_wallets_desc')"
|
||||||
|
class="q-mt-sm"
|
||||||
|
>
|
||||||
|
</q-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section>
|
||||||
|
<q-separator></q-separator>
|
||||||
|
<div class="row q-mb-md q-mt-md">
|
||||||
|
<q-btn @click="updateAccount" unelevated color="primary">
|
||||||
|
<span v-text="$t('update_account')"></span>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
</q-tab-panel>
|
||||||
<q-tab-panel name="api_acls">
|
<q-tab-panel name="api_acls">
|
||||||
<div class="row q-mb-md">
|
<div class="row q-mb-md">
|
||||||
<q-badge v-if="user.admin">
|
<q-badge v-if="user.admin">
|
||||||
|
|
|
||||||
|
|
@ -206,11 +206,15 @@ async def account(
|
||||||
request: Request,
|
request: Request,
|
||||||
user: User = Depends(check_user_exists),
|
user: User = Depends(check_user_exists),
|
||||||
):
|
):
|
||||||
|
nostr_configured = settings.is_nostr_notifications_configured()
|
||||||
|
telegram_configured = settings.is_telegram_notifications_configured()
|
||||||
return template_renderer().TemplateResponse(
|
return template_renderer().TemplateResponse(
|
||||||
request,
|
request,
|
||||||
"core/account.html",
|
"core/account.html",
|
||||||
{
|
{
|
||||||
"user": user.json(),
|
"user": user.json(),
|
||||||
|
"nostr_configured": nostr_configured,
|
||||||
|
"telegram_configured": telegram_configured,
|
||||||
"ajax": _is_ajax_request(request),
|
"ajax": _is_ajax_request(request),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -361,7 +365,6 @@ async def node_public(request: Request):
|
||||||
request,
|
request,
|
||||||
"node/public.html",
|
"node/public.html",
|
||||||
{
|
{
|
||||||
"settings": settings.dict(),
|
|
||||||
"balance": balance,
|
"balance": balance,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -398,7 +401,6 @@ async def users_index(request: Request, user: User = Depends(check_admin)):
|
||||||
{
|
{
|
||||||
"request": request,
|
"request": request,
|
||||||
"user": user.json(),
|
"user": user.json(),
|
||||||
"settings": settings.dict(),
|
|
||||||
"currencies": list(currencies.keys()),
|
"currencies": list(currencies.keys()),
|
||||||
"ajax": _is_ajax_request(request),
|
"ajax": _is_ajax_request(request),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -432,6 +432,18 @@ class NotificationsSettings(LNbitsSettings):
|
||||||
default=1_000_000, ge=0
|
default=1_000_000, ge=0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def is_nostr_notifications_configured(self) -> bool:
|
||||||
|
return (
|
||||||
|
self.lnbits_nostr_notifications_enabled
|
||||||
|
and self.lnbits_nostr_notifications_private_key is not None
|
||||||
|
)
|
||||||
|
|
||||||
|
def is_telegram_notifications_configured(self) -> bool:
|
||||||
|
return (
|
||||||
|
self.lnbits_telegram_notifications_enabled
|
||||||
|
and self.lnbits_telegram_notifications_access_token is not None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FakeWalletFundingSource(LNbitsSettings):
|
class FakeWalletFundingSource(LNbitsSettings):
|
||||||
fake_wallet_secret: str = Field(default="ToTheMoon1")
|
fake_wallet_secret: str = Field(default="ToTheMoon1")
|
||||||
|
|
|
||||||
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
|
|
@ -52,6 +52,7 @@ window.localisation.en = {
|
||||||
wallet: 'Wallet: ',
|
wallet: 'Wallet: ',
|
||||||
wallet_name: 'Wallet name',
|
wallet_name: 'Wallet name',
|
||||||
wallets: 'Wallets',
|
wallets: 'Wallets',
|
||||||
|
exclude_wallets: 'Exclude Wallets',
|
||||||
add_wallet: 'Add wallet',
|
add_wallet: 'Add wallet',
|
||||||
add_new_wallet: 'Add a new wallet',
|
add_new_wallet: 'Add a new wallet',
|
||||||
pin_wallet: 'Pin wallet',
|
pin_wallet: 'Pin wallet',
|
||||||
|
|
@ -238,9 +239,10 @@ window.localisation.en = {
|
||||||
notifications_enable_telegram_desc: 'Send notfications over Telegram',
|
notifications_enable_telegram_desc: 'Send notfications over Telegram',
|
||||||
notifications_telegram_access_token: 'Access Token',
|
notifications_telegram_access_token: 'Access Token',
|
||||||
notifications_telegram_access_token_desc: 'Access token for the bot',
|
notifications_telegram_access_token_desc: 'Access token for the bot',
|
||||||
notifications_chat_id: 'Chat ID',
|
notifications_chat_id: 'Telegram Chat ID',
|
||||||
notifications_chat_id_desc: 'Chat ID to send the notifications to',
|
notifications_chat_id_desc: 'Telegram Chat ID to send the notifications to',
|
||||||
|
notifications_excluded_wallets_desc:
|
||||||
|
'Do not send notifications for these wallets',
|
||||||
notifications_email_config: 'Email Configuration',
|
notifications_email_config: 'Email Configuration',
|
||||||
notifications_enable_email: 'Enable Email',
|
notifications_enable_email: 'Enable Email',
|
||||||
notifications_enable_email_desc: 'Send notifications over email',
|
notifications_enable_email_desc: 'Send notifications over email',
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,11 @@ window.AccountPageLogic = {
|
||||||
token_id_list: [],
|
token_id_list: [],
|
||||||
allRead: false,
|
allRead: false,
|
||||||
allWrite: false
|
allWrite: false
|
||||||
|
},
|
||||||
|
notifications: {
|
||||||
|
nostr: {
|
||||||
|
identifier: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -394,8 +399,35 @@ window.AccountPageLogic = {
|
||||||
} finally {
|
} finally {
|
||||||
this.apiAcl.password = ''
|
this.apiAcl.password = ''
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
addNostrNotificationIdentifier() {
|
||||||
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||||
|
if (!emailRegex.test(this.notifications.nostr.identifier)) {
|
||||||
|
Quasar.Notify.create({
|
||||||
|
type: 'warning',
|
||||||
|
message: 'Invalid email format.'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const identifier = this.user.extra.nostr_notification_identifiers.find(
|
||||||
|
i => i === this.notifications.nostr.identifier
|
||||||
|
)
|
||||||
|
if (identifier) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.user.extra.nostr_notification_identifiers.push(
|
||||||
|
this.notifications.nostr.identifier
|
||||||
|
)
|
||||||
|
this.notifications.nostr.identifier = ''
|
||||||
|
},
|
||||||
|
removeNostrNotificationIdentifier(identifier) {
|
||||||
|
this.user.extra.nostr_notification_identifiers =
|
||||||
|
this.user.extra.nostr_notification_identifiers.filter(
|
||||||
|
i => i !== identifier
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async created() {
|
async created() {
|
||||||
try {
|
try {
|
||||||
const {data} = await LNbits.api.getAuthenticatedUser()
|
const {data} = await LNbits.api.getAuthenticatedUser()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue