diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 3bf2a12..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1,3 +0,0 @@
-dist
-*/node_modules
-Dockerfile*
diff --git a/.gitignore b/.gitignore
index f695607..b0c2d33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
dist/
-dev-dist/
build/
.idea/
.vscode/
diff --git a/Dockerfile b/Dockerfile
index feb813f..7c2052e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM r.batts.cloud/debian:testing
+FROM alpine
LABEL org.opencontainers.image.authors="philipp.heckel@gmail.com"
LABEL org.opencontainers.image.url="https://ntfy.sh/"
diff --git a/Dockerfile-build b/Dockerfile-build
deleted file mode 100644
index 9c6d1bc..0000000
--- a/Dockerfile-build
+++ /dev/null
@@ -1,54 +0,0 @@
-FROM r.batts.cloud/golang:1.19 as builder
-
-ARG VERSION=dev
-ARG COMMIT=unknown
-
-RUN apt-get update
-RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash
-RUN apt-get install -y \
- build-essential \
- nodejs \
- python3-pip \
- python3-venv
-
-WORKDIR /app
-ADD Makefile .
-
-# docs
-ADD ./requirements.txt .
-RUN make docs-deps
-ADD ./mkdocs.yml .
-ADD ./docs ./docs
-RUN make docs-build
-
-# web
-ADD ./web/package.json ./web/package-lock.json ./web/
-RUN make web-deps
-ADD ./web ./web
-RUN make web-build
-
-# cli & server
-ADD go.mod go.sum main.go ./
-ADD ./client ./client
-ADD ./cmd ./cmd
-ADD ./log ./log
-ADD ./server ./server
-ADD ./user ./user
-ADD ./util ./util
-RUN make VERSION=$VERSION COMMIT=$COMMIT cli-linux-server
-
-FROM r.batts.cloud/debian:testing
-
-LABEL org.opencontainers.image.authors="philipp.heckel@gmail.com"
-LABEL org.opencontainers.image.url="https://ntfy.sh/"
-LABEL org.opencontainers.image.documentation="https://docs.ntfy.sh/"
-LABEL org.opencontainers.image.source="https://github.com/binwiederhier/ntfy"
-LABEL org.opencontainers.image.vendor="Philipp C. Heckel"
-LABEL org.opencontainers.image.licenses="Apache-2.0, GPL-2.0"
-LABEL org.opencontainers.image.title="ntfy"
-LABEL org.opencontainers.image.description="Send push notifications to your phone or desktop using PUT/POST"
-
-COPY --from=builder /app/dist/ntfy_linux_server/ntfy /usr/bin/ntfy
-
-EXPOSE 80/tcp
-ENTRYPOINT ["ntfy"]
diff --git a/Makefile b/Makefile
index 440bfa6..7398844 100644
--- a/Makefile
+++ b/Makefile
@@ -31,16 +31,12 @@ help:
@echo " make cli-darwin-server - Build client & server (no GoReleaser, current arch, macOS)"
@echo " make cli-client - Build client only (no GoReleaser, current arch, Linux/macOS/Windows)"
@echo
- @echo "Build dev Docker:"
- @echo " make docker-dev - Build client & server for current architecture using Docker only"
- @echo
@echo "Build web app:"
@echo " make web - Build the web app"
@echo " make web-deps - Install web app dependencies (npm install the universe)"
@echo " make web-build - Actually build the web app"
- @echo " make web-lint - Run eslint on the web app"
- @echo " make web-format - Run prettier on the web app"
- @echo " make web-format-check - Run prettier on the web app, but don't change anything"
+ @echo " make web-format - Run prettier on the web app
+ @echo " make web-format-check - Run prettier on the web app, but don't change anything
@echo
@echo "Build documentation:"
@echo " make docs - Build the documentation"
@@ -86,33 +82,23 @@ build: web docs cli
update: web-deps-update cli-deps-update docs-deps-update
docker pull alpine
-docker-dev:
- docker build \
- --file ./Dockerfile-build \
- --tag binwiederhier/ntfy:$(VERSION) \
- --tag binwiederhier/ntfy:dev \
- --build-arg VERSION=$(VERSION) \
- --build-arg COMMIT=$(COMMIT) \
- ./
-
# Ubuntu-specific
build-deps-ubuntu:
- sudo apt-get update
- sudo apt-get install -y \
+ sudo apt update
+ sudo apt install -y \
curl \
gcc-aarch64-linux-gnu \
gcc-arm-linux-gnueabi \
jq
- which pip3 || sudo apt-get install -y python3-pip
+ which pip3 || sudo apt install -y python3-pip
# Documentation
docs: docs-deps docs-build
-docs-build: venv .PHONY
- @. venv/bin/activate && \
- if ! /bin/echo -e "import sys\nif sys.version_info < (3,8):\n exit(1)" | python3; then \
+docs-build: .PHONY
+ @if ! /bin/echo -e "import sys\nif sys.version_info < (3,8):\n exit(1)" | python3; then \
if which python3.8; then \
echo "python3.8 $(shell which mkdocs) build"; \
python3.8 $(shell which mkdocs) build; \
@@ -125,15 +111,10 @@ docs-build: venv .PHONY
mkdocs build; \
fi
-venv:
- python3 -m venv ./venv
-
-docs-deps: venv .PHONY
- . venv/bin/activate && \
+docs-deps: .PHONY
pip3 install -r requirements.txt
-docs-deps-update: venv .PHONY
- . venv/bin/activate && \
+docs-deps-update: .PHONY
pip3 install -r requirements.txt --upgrade
diff --git a/client/client.go b/client/client.go
index 93cf7da..b744fa1 100644
--- a/client/client.go
+++ b/client/client.go
@@ -11,25 +11,23 @@ import (
"heckel.io/ntfy/util"
"io"
"net/http"
- "regexp"
"strings"
"sync"
"time"
)
+// Event type constants
const (
- // MessageEvent identifies a message event
- MessageEvent = "message"
+ MessageEvent = "message"
+ KeepaliveEvent = "keepalive"
+ OpenEvent = "open"
+ PollRequestEvent = "poll_request"
)
const (
maxResponseBytes = 4096
)
-var (
- topicRegex = regexp.MustCompile(`^[-_A-Za-z0-9]{1,64}$`) // Same as in server/server.go
-)
-
// Client is the ntfy client that can be used to publish and subscribe to ntfy topics
type Client struct {
Messages chan *Message
@@ -98,14 +96,8 @@ func (c *Client) Publish(topic, message string, options ...PublishOption) (*Mess
// To pass title, priority and tags, check out WithTitle, WithPriority, WithTagsList, WithDelay, WithNoCache,
// WithNoFirebase, and the generic WithHeader.
func (c *Client) PublishReader(topic string, body io.Reader, options ...PublishOption) (*Message, error) {
- topicURL, err := c.expandTopicURL(topic)
- if err != nil {
- return nil, err
- }
- req, err := http.NewRequest("POST", topicURL, body)
- if err != nil {
- return nil, err
- }
+ topicURL := c.expandTopicURL(topic)
+ req, _ := http.NewRequest("POST", topicURL, body)
for _, option := range options {
if err := option(req); err != nil {
return nil, err
@@ -141,14 +133,11 @@ func (c *Client) PublishReader(topic string, body io.Reader, options ...PublishO
// By default, all messages will be returned, but you can change this behavior using a SubscribeOption.
// See WithSince, WithSinceAll, WithSinceUnixTime, WithScheduled, and the generic WithQueryParam.
func (c *Client) Poll(topic string, options ...SubscribeOption) ([]*Message, error) {
- topicURL, err := c.expandTopicURL(topic)
- if err != nil {
- return nil, err
- }
ctx := context.Background()
messages := make([]*Message, 0)
msgChan := make(chan *Message)
errChan := make(chan error)
+ topicURL := c.expandTopicURL(topic)
log.Debug("%s Polling from topic", util.ShortTopicURL(topicURL))
options = append(options, WithPoll())
go func() {
@@ -177,18 +166,15 @@ func (c *Client) Poll(topic string, options ...SubscribeOption) ([]*Message, err
// Example:
//
// c := client.New(client.NewConfig())
-// subscriptionID, _ := c.Subscribe("mytopic")
+// subscriptionID := c.Subscribe("mytopic")
// for m := range c.Messages {
// fmt.Printf("New message: %s", m.Message)
// }
-func (c *Client) Subscribe(topic string, options ...SubscribeOption) (string, error) {
- topicURL, err := c.expandTopicURL(topic)
- if err != nil {
- return "", err
- }
+func (c *Client) Subscribe(topic string, options ...SubscribeOption) string {
c.mu.Lock()
defer c.mu.Unlock()
subscriptionID := util.RandomString(10)
+ topicURL := c.expandTopicURL(topic)
log.Debug("%s Subscribing to topic", util.ShortTopicURL(topicURL))
ctx, cancel := context.WithCancel(context.Background())
c.subscriptions[subscriptionID] = &subscription{
@@ -197,7 +183,7 @@ func (c *Client) Subscribe(topic string, options ...SubscribeOption) (string, er
cancel: cancel,
}
go handleSubscribeConnLoop(ctx, c.Messages, topicURL, subscriptionID, options...)
- return subscriptionID, nil
+ return subscriptionID
}
// Unsubscribe unsubscribes from a topic that has been previously subscribed to using the unique
@@ -213,16 +199,31 @@ func (c *Client) Unsubscribe(subscriptionID string) {
sub.cancel()
}
-func (c *Client) expandTopicURL(topic string) (string, error) {
+// UnsubscribeAll unsubscribes from a topic that has been previously subscribed with Subscribe.
+// If there are multiple subscriptions matching the topic, all of them are unsubscribed from.
+//
+// A topic can be either a full URL (e.g. https://myhost.lan/mytopic), a short URL which is then prepended https://
+// (e.g. myhost.lan -> https://myhost.lan), or a short name which is expanded using the default host in the
+// config (e.g. mytopic -> https://ntfy.sh/mytopic).
+func (c *Client) UnsubscribeAll(topic string) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ topicURL := c.expandTopicURL(topic)
+ for _, sub := range c.subscriptions {
+ if sub.topicURL == topicURL {
+ delete(c.subscriptions, sub.ID)
+ sub.cancel()
+ }
+ }
+}
+
+func (c *Client) expandTopicURL(topic string) string {
if strings.HasPrefix(topic, "http://") || strings.HasPrefix(topic, "https://") {
- return topic, nil
+ return topic
} else if strings.Contains(topic, "/") {
- return fmt.Sprintf("https://%s", topic), nil
+ return fmt.Sprintf("https://%s", topic)
}
- if !topicRegex.MatchString(topic) {
- return "", fmt.Errorf("invalid topic name: %s", topic)
- }
- return fmt.Sprintf("%s/%s", c.config.DefaultHost, topic), nil
+ return fmt.Sprintf("%s/%s", c.config.DefaultHost, topic)
}
func handleSubscribeConnLoop(ctx context.Context, msgChan chan *Message, topicURL, subcriptionID string, options ...SubscribeOption) {
diff --git a/client/client_test.go b/client/client_test.go
index f0b15a3..a71ea5c 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -21,7 +21,7 @@ func TestClient_Publish_Subscribe(t *testing.T) {
defer test.StopServer(t, s, port)
c := client.New(newTestConfig(port))
- subscriptionID, _ := c.Subscribe("mytopic")
+ subscriptionID := c.Subscribe("mytopic")
time.Sleep(time.Second)
msg, err := c.Publish("mytopic", "some message")
diff --git a/cmd/subscribe.go b/cmd/subscribe.go
index c85c468..2691e6a 100644
--- a/cmd/subscribe.go
+++ b/cmd/subscribe.go
@@ -72,7 +72,7 @@ ntfy subscribe TOPIC COMMAND
$NTFY_TITLE $title, $t Message title
$NTFY_PRIORITY $priority, $prio, $p Message priority (1=min, 5=max)
$NTFY_TAGS $tags, $tag, $ta Message tags (comma separated list)
- $NTFY_RAW $raw Raw JSON message
+ $NTFY_RAW $raw Raw JSON message
Examples:
ntfy sub mytopic 'notify-send "$m"' # Execute command for incoming messages
@@ -194,10 +194,7 @@ func doSubscribe(c *cli.Context, cl *client.Client, conf *client.Config, topic,
topicOptions = append(topicOptions, auth)
}
- subscriptionID, err := cl.Subscribe(s.Topic, topicOptions...)
- if err != nil {
- return err
- }
+ subscriptionID := cl.Subscribe(s.Topic, topicOptions...)
if s.Command != "" {
cmds[subscriptionID] = s.Command
} else if conf.DefaultCommand != "" {
@@ -207,10 +204,7 @@ func doSubscribe(c *cli.Context, cl *client.Client, conf *client.Config, topic,
}
}
if topic != "" {
- subscriptionID, err := cl.Subscribe(topic, options...)
- if err != nil {
- return err
- }
+ subscriptionID := cl.Subscribe(topic, options...)
cmds[subscriptionID] = command
}
for m := range cl.Messages {
diff --git a/docs/develop.md b/docs/develop.md
index baab3f3..a53c503 100644
--- a/docs/develop.md
+++ b/docs/develop.md
@@ -163,15 +163,6 @@ $ make release-snapshot
During development, you may want to be more picky and build only certain things. Here are a few examples.
-### Build a Docker image only for Linux
-
-This is useful to test the final build with web app, docs, and server without any dependencies locally
-
-``` shell
-$ make docker-dev
-$ docker run --rm -p 80:80 binwiederhier/ntfy:dev serve
-```
-
### Build the ntfy binary
To build only the `ntfy` binary **without the web app or documentation**, use the `make cli-...` targets:
diff --git a/docs/releases.md b/docs/releases.md
index 0e93b67..71fceb1 100644
--- a/docs/releases.md
+++ b/docs/releases.md
@@ -1225,8 +1225,6 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
**Bug fixes:**
* Support encoding any header as RFC 2047 ([#737](https://github.com/binwiederhier/ntfy/issues/737), thanks to [@cfouche3005](https://github.com/cfouche3005) for reporting)
-* Do not forward poll requests for UnifiedPush messages (no ticket, thanks to NoName for reporting)
-* Fix `ntfy pub %` segfaulting ([#760](https://github.com/binwiederhier/ntfy/issues/760), thanks to [@clesmian](https://github.com/clesmian) for reporting)
**Maintenance:**
diff --git a/server/server.go b/server/server.go
index d2fac01..ac54aa5 100644
--- a/server/server.go
+++ b/server/server.go
@@ -760,7 +760,7 @@ func (s *Server) handlePublishInternal(r *http.Request, v *visitor) (*message, e
if s.config.TwilioAccount != "" && call != "" {
go s.callPhone(v, r, m, call)
}
- if s.config.UpstreamBaseURL != "" && !unifiedpush { // UP messages are not sent to upstream
+ if s.config.UpstreamBaseURL != "" {
go s.forwardPollRequest(v, m)
}
} else {
diff --git a/server/server_test.go b/server/server_test.go
index d7c4a7c..73df276 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -2559,29 +2559,6 @@ func TestServer_UpstreamBaseURL_With_Access_Token_Success(t *testing.T) {
})
}
-func TestServer_UpstreamBaseURL_DoNotForwardUnifiedPush(t *testing.T) {
- upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- t.Fatal("UnifiedPush messages should not be forwarded")
- }))
- defer upstreamServer.Close()
-
- c := newTestConfigWithAuthFile(t)
- c.BaseURL = "http://myserver.internal"
- c.UpstreamBaseURL = upstreamServer.URL
- s := newTestServer(t, c)
-
- // Send UP message, this should not forward to upstream server
- response := request(t, s, "PUT", "/mytopic?up=1", `hi there`, nil)
- require.Equal(t, 200, response.Code)
- m := toMessage(t, response.Body.String())
- require.NotEmpty(t, m.ID)
- require.Equal(t, "hi there", m.Message)
-
- // Forwarding is done asynchronously, so wait a bit.
- // This ensures that the t.Fatal above is actually not triggered.
- time.Sleep(500 * time.Millisecond)
-}
-
func newTestConfig(t *testing.T) *Config {
conf := NewConfig()
conf.BaseURL = "http://127.0.0.1:12345"
diff --git a/web/public/static/langs/cs.json b/web/public/static/langs/cs.json
index 6b967c8..aeff195 100644
--- a/web/public/static/langs/cs.json
+++ b/web/public/static/langs/cs.json
@@ -355,15 +355,5 @@
"account_upgrade_dialog_billing_contact_website": "Otázky týkající se fakturace naleznete na našich webových stránkách.",
"account_upgrade_dialog_tier_features_reservations_one": "{{reservations}} rezervované téma",
"account_upgrade_dialog_tier_features_messages_one": "{{messages}} denní zpráva",
- "account_upgrade_dialog_tier_features_emails_one": "{{emails}} denní e-mail",
- "publish_dialog_call_label": "Telefonát",
- "publish_dialog_call_reset": "Odstranit telefonát",
- "publish_dialog_chip_call_label": "Telefonát",
- "account_basics_phone_numbers_title": "Telefonní čísla",
- "account_basics_phone_numbers_dialog_description": "Pro oznámení prostřednictvím tel. hovoru, musíte přidat a ověřit alespoň jedno telefonní číslo. Ověření lze provést pomocí SMS nebo telefonátu.",
- "account_basics_phone_numbers_description": "K oznámení telefonátem",
- "account_basics_phone_numbers_no_phone_numbers_yet": "Zatím žádná telefonní čísla",
- "account_basics_phone_numbers_copied_to_clipboard": "Telefonní číslo zkopírováno do schránky",
- "publish_dialog_chip_call_no_verified_numbers_tooltip": "Žádná ověřená telefonní čísla",
- "publish_dialog_call_item": "Vytočit číslo {{number}}"
+ "account_upgrade_dialog_tier_features_emails_one": "{{emails}} denní e-mail"
}
diff --git a/web/public/static/langs/es.json b/web/public/static/langs/es.json
index 62ecdaf..3166a52 100644
--- a/web/public/static/langs/es.json
+++ b/web/public/static/langs/es.json
@@ -355,31 +355,5 @@
"account_upgrade_dialog_billing_contact_email": "Para preguntas sobre facturación, por favor contáctenos directamente.",
"account_upgrade_dialog_tier_features_messages_one": "{{messages}} mensaje diario",
"account_upgrade_dialog_tier_features_emails_one": "{{emails}} correo electrónico diario",
- "account_upgrade_dialog_tier_features_reservations_one": "{{reservations}} tema reservado",
- "publish_dialog_call_label": "Llamada telefónica",
- "publish_dialog_call_placeholder": "Número de teléfono al cual llamar con el mensaje, por ejemplo +12223334444, o \"sí\"",
- "publish_dialog_chip_call_label": "Llamada telefónica",
- "account_basics_phone_numbers_title": "Números de teléfono",
- "account_basics_phone_numbers_description": "Para notificaciones por llamada teléfonica",
- "account_basics_phone_numbers_no_phone_numbers_yet": "Aún no hay números de teléfono",
- "account_basics_phone_numbers_dialog_number_label": "Número de teléfono",
- "account_basics_phone_numbers_dialog_number_placeholder": "p. ej. +1222333444",
- "account_basics_phone_numbers_dialog_verify_button_sms": "Envía SMS",
- "account_basics_phone_numbers_dialog_verify_button_call": "Llámame",
- "account_basics_phone_numbers_dialog_code_label": "Código de verificación",
- "account_basics_phone_numbers_dialog_channel_sms": "SMS",
- "account_basics_phone_numbers_dialog_channel_call": "Llamar",
- "account_usage_calls_title": "Llamadas telefónicas realizadas",
- "account_usage_calls_none": "No se pueden hacer llamadas telefónicas con esta cuenta",
- "account_upgrade_dialog_tier_features_calls_one": "{{llamadas}} llamadas telefónicas diarias",
- "account_upgrade_dialog_tier_features_calls_other": "{{llamadas}} llamadas telefónicas diarias",
- "account_upgrade_dialog_tier_features_no_calls": "No hay llamadas telefónicas",
- "publish_dialog_call_reset": "Eliminar llamada telefónica",
- "account_basics_phone_numbers_dialog_description": "Para utilizar la función de notificación de llamadas, tiene que añadir y verificar al menos un número de teléfono. La verificación puede realizarse mediante un SMS o una llamada telefónica.",
- "account_basics_phone_numbers_copied_to_clipboard": "Número de teléfono copiado al portapapeles",
- "account_basics_phone_numbers_dialog_check_verification_button": "Confirmar código",
- "account_basics_phone_numbers_dialog_title": "Agregar número de teléfono",
- "account_basics_phone_numbers_dialog_code_placeholder": "p.ej. 123456",
- "publish_dialog_call_item": "Llamar al número de teléfono {{number}}",
- "publish_dialog_chip_call_no_verified_numbers_tooltip": "No hay números de teléfono verificados"
+ "account_upgrade_dialog_tier_features_reservations_one": "{{reservations}} tema reservado"
}
diff --git a/web/public/static/langs/id.json b/web/public/static/langs/id.json
index 48fcda0..76c9d1d 100644
--- a/web/public/static/langs/id.json
+++ b/web/public/static/langs/id.json
@@ -379,7 +379,5 @@
"account_basics_phone_numbers_dialog_channel_sms": "SMS",
"account_upgrade_dialog_tier_features_calls_one": "{{calls}} panggilan telepon harian",
"account_upgrade_dialog_tier_features_no_calls": "Tidak ada panggilan telepon",
- "account_basics_phone_numbers_dialog_code_label": "Kode verifikasi",
- "publish_dialog_call_item": "Panggil nomor telepon {{number}}",
- "publish_dialog_chip_call_no_verified_numbers_tooltip": "Tidak ada nomor telepon terverifikasi"
+ "account_basics_phone_numbers_dialog_code_label": "Kode verifikasi"
}
diff --git a/web/public/static/langs/nl.json b/web/public/static/langs/nl.json
index 8ccb629..ca7a2a1 100644
--- a/web/public/static/langs/nl.json
+++ b/web/public/static/langs/nl.json
@@ -355,30 +355,5 @@
"prefs_reservations_table_topic_header": "Onderwerp",
"prefs_reservations_table_access_header": "Toegang",
"prefs_reservations_table_everyone_read_write": "Iedereen kan publiceren en abonneren",
- "prefs_reservations_table_not_subscribed": "Niet geabonneerd",
- "publish_dialog_call_label": "Telefoongesprek",
- "publish_dialog_call_reset": "Telefoongesprek verwijderen",
- "publish_dialog_chip_call_label": "Telefoongesprek",
- "account_basics_phone_numbers_title": "Telefoonnummers",
- "account_basics_phone_numbers_description": "Voor meldingen via telefoongesprekken",
- "account_basics_phone_numbers_no_phone_numbers_yet": "Nog geen telefoonnummers",
- "account_basics_phone_numbers_dialog_verify_button_call": "Bel me",
- "account_upgrade_dialog_tier_features_calls_one": "{{calls}} dagelijkse telefoontjes",
- "account_basics_phone_numbers_copied_to_clipboard": "Telefoonnummer gekopieerd naar klembord",
- "publish_dialog_call_item": "Bel telefoonnummer {{nummer}}",
- "account_basics_phone_numbers_dialog_check_verification_button": "Bevestig code",
- "publish_dialog_chip_call_no_verified_numbers_tooltip": "Geen geverifieerde telefoonnummers",
- "account_basics_phone_numbers_dialog_channel_call": "Telefoongesprek",
- "account_basics_phone_numbers_dialog_number_label": "Telefoonnummer",
- "account_basics_phone_numbers_dialog_channel_sms": "SMS",
- "account_basics_phone_numbers_dialog_code_placeholder": "bijv. 123456",
- "account_upgrade_dialog_tier_features_calls_other": "{{calls}} dagelijkse telefoontjes",
- "account_upgrade_dialog_tier_features_no_calls": "Geen telefoontjes",
- "account_basics_phone_numbers_dialog_description": "Als u de functie voor oproepmeldingen wilt gebruiken, moet u ten minste één telefoonnummer toevoegen en verifiëren. Verificatie kan worden gedaan via sms of een telefoontje.",
- "account_basics_phone_numbers_dialog_title": "Telefoonnummer toevoegen",
- "account_basics_phone_numbers_dialog_number_placeholder": "bijv. +1222333444",
- "account_basics_phone_numbers_dialog_verify_button_sms": "Stuur SMS",
- "account_basics_phone_numbers_dialog_code_label": "Verificatiecode",
- "account_usage_calls_title": "Aantal telefoontjes",
- "account_usage_calls_none": "Met dit account kan niet worden gebeld"
+ "prefs_reservations_table_not_subscribed": "Niet geabonneerd"
}
diff --git a/web/public/static/langs/pt.json b/web/public/static/langs/pt.json
index 57d5656..bf753c9 100644
--- a/web/public/static/langs/pt.json
+++ b/web/public/static/langs/pt.json
@@ -214,17 +214,5 @@
"login_link_signup": "Registar",
"action_bar_reservation_add": "Reservar tópico",
"action_bar_sign_up": "Registar",
- "nav_button_account": "Conta",
- "common_copy_to_clipboard": "Copiar",
- "nav_upgrade_banner_label": "Atualizar para ntfy Pro",
- "alert_not_supported_context_description": "Notificações são suportadas apenas sobre HTTPS. Essa é uma limitação da API de Notificações.",
- "display_name_dialog_title": "Alterar nome mostrado",
- "display_name_dialog_description": "Configura um nome alternativo ao tópico que é mostrado na lista de assinaturas. Isto ajuda a identificar tópicos com nomes complicados mais facilmente.",
- "display_name_dialog_placeholder": "Nome exibido",
- "reserve_dialog_checkbox_label": "Reservar tópico e configurar acesso",
- "publish_dialog_call_label": "Chamada telefônica",
- "publish_dialog_call_placeholder": "Número de telefone para ligar com a mensagem, ex: +12223334444, ou 'Sim'",
- "publish_dialog_call_reset": "Remover chamada telefônica",
- "publish_dialog_chip_call_label": "Chamada telefônica",
- "subscribe_dialog_subscribe_button_generate_topic_name": "Gerar nome"
+ "nav_button_account": "Conta"
}
diff --git a/web/public/static/langs/sv.json b/web/public/static/langs/sv.json
index bc4a540..31e809c 100644
--- a/web/public/static/langs/sv.json
+++ b/web/public/static/langs/sv.json
@@ -355,30 +355,5 @@
"reservation_delete_dialog_action_keep_title": "Behåll cachade meddelanden och bilagor",
"reservation_delete_dialog_action_keep_description": "Meddelanden och bilagor som lagras på servern blir offentligt synliga för personer som känner till ämnesnamnet.",
"reservation_delete_dialog_action_delete_title": "Ta bort meddelanden och bilagor som sparats i cacheminnet",
- "reservation_delete_dialog_description": "Om du tar bort en reservation ger du upp äganderätten till ämnet och låter andra reservera det. Du kan behålla eller radera befintliga meddelanden och bilagor.",
- "publish_dialog_call_label": "Telefonsamtal",
- "publish_dialog_call_reset": "Ta bort telefonsamtal",
- "publish_dialog_chip_call_label": "Telefonsamtal",
- "account_basics_phone_numbers_title": "Telefonnummer",
- "account_basics_phone_numbers_description": "För notifieringar via telefonsamtal",
- "account_basics_phone_numbers_no_phone_numbers_yet": "Inga telefonnummer ännu",
- "account_basics_phone_numbers_copied_to_clipboard": "Telefonnummer kopierat till urklipp",
- "account_basics_phone_numbers_dialog_title": "Lägga till telefonnummer",
- "account_basics_phone_numbers_dialog_number_label": "Telefonnummer",
- "account_basics_phone_numbers_dialog_number_placeholder": "t.ex. +1222333444",
- "account_basics_phone_numbers_dialog_verify_button_sms": "Skicka SMS",
- "account_basics_phone_numbers_dialog_verify_button_call": "Ring mig",
- "account_basics_phone_numbers_dialog_code_label": "Verifieringskod",
- "account_basics_phone_numbers_dialog_channel_call": "Ring",
- "account_usage_calls_title": "Telefonsamtal som gjorts",
- "account_usage_calls_none": "Inga telefonsamtal kan göras med detta konto",
- "publish_dialog_call_item": "Ring telefonnummer {{number}}",
- "publish_dialog_chip_call_no_verified_numbers_tooltip": "Inga verifierade telefonnummer",
- "account_basics_phone_numbers_dialog_description": "För att använda funktionen för samtalsavisering måste du lägga till och verifiera minst ett telefonnummer. Verifieringen kan göras via SMS eller ett telefonsamtal.",
- "account_basics_phone_numbers_dialog_code_placeholder": "t.ex. 123456",
- "account_basics_phone_numbers_dialog_check_verification_button": "Bekräfta kod",
- "account_basics_phone_numbers_dialog_channel_sms": "SMS",
- "account_upgrade_dialog_tier_features_calls_other": "{{calls}} dagliga telefonsamtal",
- "account_upgrade_dialog_tier_features_no_calls": "Inga telefonsamtal",
- "account_upgrade_dialog_tier_features_calls_one": "{{calls}} dagliga telefonsamtal"
+ "reservation_delete_dialog_description": "Om du tar bort en reservation ger du upp äganderätten till ämnet och låter andra reservera det. Du kan behålla eller radera befintliga meddelanden och bilagor."
}
diff --git a/web/public/static/langs/uk.json b/web/public/static/langs/uk.json
index 32a3079..7d995dd 100644
--- a/web/public/static/langs/uk.json
+++ b/web/public/static/langs/uk.json
@@ -352,34 +352,5 @@
"account_upgrade_dialog_reservations_warning_other": "Обраний рівень дозволяє менше зарезервованих тем, ніж ваш поточний рівень. Перш ніж змінити свій рівень, будь ласка, видаліть принаймні {{count}} резервувань. Ви можете видалити резервування в Налаштуваннях.",
"account_upgrade_dialog_button_cancel": "Скасувати",
"account_upgrade_dialog_button_redirect_signup": "Зареєструватися зараз",
- "account_upgrade_dialog_button_pay_now": "Оплатити зараз і підписатися",
- "prefs_reservations_add_button": "Додати зарезервовану тему",
- "prefs_reservations_edit_button": "Редагувати доступ до теми",
- "prefs_reservations_limit_reached": "Ви досягли ліміту зарезервованих тем.",
- "prefs_reservations_table_click_to_subscribe": "Натисніть, щоб підписатися",
- "prefs_reservations_table_topic_header": "Тема",
- "prefs_reservations_description": "Тут ви можете зарезервувати назви тем для особистого користування. Резервування теми дає вам право власності на тему і дозволяє визначати права доступу до неї інших користувачів.",
- "prefs_reservations_table": "Таблиця зарезервованих тем",
- "prefs_reservations_table_access_header": "Доступ",
- "prefs_reservations_table_everyone_deny_all": "Тільки я можу публікувати та підписуватись",
- "prefs_reservations_table_everyone_read_only": "Я можу публікувати та підписуватись, кожен може підписатися",
- "prefs_reservations_table_everyone_write_only": "Я можу публікувати і підписуватися, кожен може публікувати",
- "prefs_reservations_table_everyone_read_write": "Кожен може публікувати та підписуватися",
- "prefs_reservations_table_not_subscribed": "Не підписаний",
- "prefs_reservations_dialog_title_add": "Зарезервувати тему",
- "prefs_reservations_dialog_title_edit": "Редагувати зарезервовану тему",
- "prefs_reservations_title": "Зарезервовані теми",
- "prefs_reservations_delete_button": "Скинути доступ до теми",
- "prefs_reservations_dialog_description": "Резервування теми дає вам право власності на цю тему і дозволяє визначати права доступу до неї інших користувачів.",
- "prefs_reservations_dialog_topic_label": "Тема",
- "prefs_reservations_dialog_access_label": "Доступ",
- "reservation_delete_dialog_description": "Видалення резервування позбавляє вас права власності на тему і дозволяє іншим зарезервувати її. Ви можете зберегти або видалити існуючі повідомлення і вкладення.",
- "reservation_delete_dialog_submit_button": "Видалити резервування",
- "publish_dialog_call_item": "Телефонувати за номером {{номер}}",
- "publish_dialog_chip_call_no_verified_numbers_tooltip": "Немає підтверджених номерів телефонів",
- "prefs_reservations_dialog_title_delete": "Видалити резервування теми",
- "reservation_delete_dialog_action_delete_title": "Видалення кешованих повідомлень і вкладень",
- "reservation_delete_dialog_action_keep_title": "Збереження кешованих повідомлень і вкладень",
- "reservation_delete_dialog_action_keep_description": "Повідомлення і вкладення, які кешуються на сервері, стають загальнодоступними для людей, які знають назву теми.",
- "reservation_delete_dialog_action_delete_description": "Кешовані повідомлення та вкладення будуть видалені назавжди. Ця дія не може бути скасована."
+ "account_upgrade_dialog_button_pay_now": "Оплатити зараз і підписатися"
}
diff --git a/web/src/components/hooks.js b/web/src/components/hooks.js
index 6b68188..b9c5536 100644
--- a/web/src/components/hooks.js
+++ b/web/src/components/hooks.js
@@ -47,13 +47,6 @@ export const useConnectionListeners = (account, subscriptions, users) => {
const handleMessage = async (subscriptionId, message) => {
const subscription = await subscriptionManager.get(subscriptionId);
-
- // Race condition: sometimes the subscription is already unsubscribed from account
- // sync before the message is handled
- if (!subscription) {
- return;
- }
-
if (subscription.internal) {
await handleInternalMessage(message);
} else {