Compare commits

...

2 Commits

Author SHA1 Message Date
Kailash Nadh
6417f30d77 Stop recording to send count on campaign creation.
Prior to this patch, when a new campaign was created, the `to send` count of
subscribers was counted from the subscriptions and added to the campaign to be
displayed on the frontend. However, this had several issues:

- On large databases, the count can be extremely slow, slowing down campaign
  creation.
- The count was purely cosmetic. When a campaign starts, it's recounted (for real)
  anyway.
- The count was also inaccurate. Changing the list on a campaign, or changes to
  the subscribers in a list never updated the count on the campaign, rendering
  it wholly incorrect sometimes.

Closes #2431.
2025-11-23 12:13:50 +05:30
Kailash Nadh
12b80699d9 Remove incorrect settings dependency on Media UI.
The media UI was calling getSettings(), which requires the `settings:get`
permission to get the uploader type, which creates a bad permission dependecy.
This patch removes this dependecy and instead exposes the media provider
via `/api/config` (`serverConfig` in the frontend).

Fixes #2747.
2025-11-23 11:45:33 +05:30
3 changed files with 9 additions and 21 deletions

View File

@@ -22,6 +22,7 @@ type serverConfig struct {
CaptchaKey null.String `json:"captcha_key"`
AltchaComplexity int `json:"altcha_complexity"`
} `json:"public_subscription"`
MediaProvider string `json:"media_provider"`
Messengers []string `json:"messengers"`
Langs []i18nLang `json:"langs"`
Lang string `json:"lang"`
@@ -54,6 +55,8 @@ func (a *App) GetServerConfig(c echo.Context) error {
out.PublicSubscription.CaptchaKey = null.StringFrom(a.cfg.Security.Captcha.HCaptcha.Key)
}
out.MediaProvider = a.cfg.MediaUpload.Provider
// Language list.
langList, err := getI18nLangList(a.fs)
if err != nil {

View File

@@ -3,7 +3,7 @@
<h1 class="title is-4">
{{ $t('media.title') }}
<span v-if="media.results && media.results.length > 0">({{ media.results.length }})</span>
<span class="has-text-grey-light"> / {{ settings['upload.provider'] }}</span>
<span class="has-text-grey-light"> / {{ serverConfig.media_provider }}</span>
</h1>
<b-loading :active="isProcessing || loading.media" />
@@ -22,14 +22,14 @@
</div>
</form>
</div>
<div class="column is-narrow">
<div v-if="$can('media:manage')" class="column is-narrow">
<b-button @click="onToggleForm" icon-left="file-upload-outline" data-cy="btn-toggle-upload">
{{ $t('media.upload') }}
</b-button>
</div>
</div>
<b-collapse v-model="showUploadForm" animation="">
<b-collapse v-if="$can('media:manage')" v-model="showUploadForm" animation="">
<form @submit.prevent="onSubmit" class="mb-6" data-cy="upload">
<div>
<b-field :label="$t('media.upload')">
@@ -213,7 +213,7 @@ export default Vue.extend({
},
computed: {
...mapState(['loading', 'media', 'settings']),
...mapState(['loading', 'media', 'serverConfig']),
isProcessing() {
if (this.toUpload > 0 && this.uploaded < this.toUpload) {
@@ -224,7 +224,6 @@ export default Vue.extend({
},
mounted() {
this.$api.getSettings();
this.$api.getMedia();
if (this.$utils.getPref('media.upload')) {

View File

@@ -22,20 +22,6 @@ WITH tpl AS (
END
LIMIT 1
),
counts AS (
-- This is going to be slow on large databases.
SELECT
COALESCE(COUNT(DISTINCT sl.subscriber_id), 0) AS to_send, COALESCE(MAX(s.id), 0) AS max_sub_id
FROM subscriber_lists sl
JOIN lists l ON sl.list_id = l.id
JOIN subscribers s ON sl.subscriber_id = s.id
WHERE sl.list_id = ANY($14::INT[])
AND s.status != 'blocklisted'
AND (
(l.optin = 'double' AND sl.status = 'confirmed') OR
(l.optin != 'double' AND sl.status != 'unsubscribed')
)
),
camp AS (
INSERT INTO campaigns (uuid, type, name, subject, from_email, body, altbody,
content_type, send_at, headers, tags, messenger, template_id, to_send,
@@ -47,8 +33,8 @@ camp AS (
$8::content_type,
$9, $10, $11, $12,
(SELECT id FROM tpl),
(SELECT to_send FROM counts),
(SELECT max_sub_id FROM counts),
0,
0,
$15, $16,
-- archive_template_id
$17,