2 Commits

Author SHA1 Message Date
16a9c73624 Release v25.11.12
All checks were successful
Production deployment / Build (release) Successful in 38s
Staging deployment / Build (release) Successful in 1m10s
CI / Checks (push) Successful in 4m24s
Production deployment / Deploy (release) Successful in 2m15s
Staging deployment / Deploy (release) Successful in 1m55s
2025-11-12 20:55:56 +01:00
b358ef6686 BTHLABS-65: Implement support for Win 11 payload in PWA share sheet endpoint
Co-authored-by: Tomek Wójcik <labs@tomekwojcik.pl>
Co-committed-by: Tomek Wójcik <labs@tomekwojcik.pl>
2025-11-12 19:30:33 +00:00
21 changed files with 122 additions and 90 deletions

View File

@@ -66,7 +66,7 @@ $ docker run --rm -it \
-e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME=hotpocket \
-e HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD=hotpocketm4st3r \
-p 8000:8000 \
docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.11.06-01
docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.11.12-01
```
The command above will set up and start the application. The SQLite file will

View File

@@ -1,6 +1,6 @@
services:
backend:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.11.06-01"
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:aio-v25.11.12-01"
environment:
HOTPOCKET_BACKEND_SECRET_KEY: "thisisntright"
HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME: "hotpocket"

View File

@@ -8,7 +8,7 @@ x-backend-environment: &x-backend-environment
services:
webapp:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.11.06-01"
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.11.12-01"
environment:
<<: *x-backend-environment
HOTPOCKET_BACKEND_ALLOWED_HOSTS: "app.staging.hotpocket.bthlab.bthlabs.net"
@@ -21,7 +21,7 @@ services:
restart: "unless-stopped"
admin:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.11.06-01"
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.11.12-01"
environment:
<<: *x-backend-environment
HOTPOCKET_BACKEND_APP: "admin"
@@ -35,7 +35,7 @@ services:
restart: "unless-stopped"
celery-worker:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.11.06-01"
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.11.12-01"
command:
- "/srv/venv/bin/celery"
- "-A"
@@ -57,7 +57,7 @@ services:
restart: "unless-stopped"
celery-beat:
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.11.06-01"
image: "docker-hosted.nexus.bthlabs.pl/hotpocket/backend:deployment-v25.11.12-01"
command:
- "/srv/venv/bin/celery"
- "-A"

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "hotpocket-workspace"
version = "25.11.06"
version = "25.11.12"
description = "HotPocket Workspace"
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
license = "Apache-2.0"

View File

@@ -713,7 +713,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "iOS (Share Extension)/iOS (Share Extension).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "iOS (Share Extension)/Info.plist";
@@ -726,7 +726,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
PRODUCT_NAME = "Save to HotPocket";
SDKROOT = iphoneos;
@@ -746,7 +746,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "iOS (Share Extension)/iOS (Share Extension).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "iOS (Share Extension)/Info.plist";
@@ -759,7 +759,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
PRODUCT_NAME = "Save to HotPocket";
SDKROOT = iphoneos;
@@ -779,7 +779,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "iOS (Extension)/Info.plist";
@@ -792,7 +792,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -814,7 +814,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "iOS (Extension)/Info.plist";
@@ -827,7 +827,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -853,7 +853,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = "iOS (App)/HotPocket (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "iOS (App)/Info.plist";
@@ -873,7 +873,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -899,7 +899,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = "iOS (App)/HotPocket (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "iOS (App)/Info.plist";
@@ -919,7 +919,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -945,7 +945,7 @@
CODE_SIGN_ENTITLEMENTS = "macOS (Extension)/HotPocket.entitlements";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
@@ -960,7 +960,7 @@
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -980,7 +980,7 @@
CODE_SIGN_ENTITLEMENTS = "macOS (Extension)/HotPocket.entitlements";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
@@ -995,7 +995,7 @@
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -1017,7 +1017,7 @@
CODE_SIGN_ENTITLEMENTS = "macOS (App)/HotPocket.entitlements";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1033,7 +1033,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -1056,7 +1056,7 @@
CODE_SIGN_ENTITLEMENTS = "macOS (App)/HotPocket.entitlements";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1072,7 +1072,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -1206,7 +1206,7 @@
CODE_SIGN_ENTITLEMENTS = "macOS (Share Extension)/macOS (Share Extension).entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1220,7 +1220,7 @@
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
PRODUCT_NAME = "Save to HotPocket";
REGISTER_APP_GROUPS = YES;
@@ -1236,7 +1236,7 @@
CODE_SIGN_ENTITLEMENTS = "macOS (Share Extension)/macOS (Share Extension).entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2025110601;
CURRENT_PROJECT_VERSION = 2025111201;
DEVELOPMENT_TEAM = 648728X64K;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1250,7 +1250,7 @@
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 25.11.06;
MARKETING_VERSION = 25.11.12;
PRODUCT_BUNDLE_IDENTIFIER = pl.bthlabs.HotPocket.ShareExtension;
PRODUCT_NAME = "Save to HotPocket";
REGISTER_APP_GROUPS = YES;

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "hotpocket-apple"
version = "25.11.06"
version = "25.11.12"
description = "HotPocket Apple Integrations"
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
license = "Apache-2.0"

View File

@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import annotations
version = '25.11.06'
version = '25.11.12'

View File

@@ -78,9 +78,13 @@ urlpatterns = [
name='ui.integrations.ios.shortcut',
),
path(
# Turns out PWAs can register a share target in Windows 11 when
# installed through Edge. Neat, too. I wish I knew this when I defined
# this URL path. Now it's gonna stay forever like this due to backwards
# compat ;).
'integrations/android/share-sheet/',
integrations.android.share_sheet,
name='ui.integrations.android.share_sheet',
integrations.pwa.share_sheet,
name='ui.integrations.pwa.share_sheet',
),
path(
'integrations/extension/authenticate/',

View File

@@ -1,3 +1,3 @@
from . import android # noqa: F401
from . import extension # noqa: F401
from . import ios # noqa: F401
from . import pwa # noqa: F401

View File

@@ -21,10 +21,14 @@ def share_sheet(request: HttpRequest) -> HttpResponse:
try:
assert request.user.is_anonymous is False, 'Login required'
assert 'text' in request.POST, 'Bad request: Missing `text`'
url = request.POST['text'].split('\n')[0].strip()
assert url != '', 'Bad request: Empty `text`'
url: str = ''
if 'url' in request.POST:
url = request.POST['url'].strip()
elif 'text' in request.POST:
url = request.POST['text'].split('\n')[0].strip()
assert url != '', 'Bad request: Empty `url`'
return CreateSaveWorkflow().run(
request=request,

View File

@@ -50,7 +50,7 @@ def manifest_json(request: HttpRequest) -> JsonResponse:
'scope': '/',
'share_target': {
'action': request.build_absolute_uri(
reverse('ui.integrations.android.share_sheet'),
reverse('ui.integrations.pwa.share_sheet'),
),
'method': 'POST',
'enctype': 'multipart/form-data',

View File

@@ -13,7 +13,7 @@ cat <<EOF
|_|
production
HotPocket v25.11.06 [${HOTPOCKET_BACKEND_IMAGE_ID}] (https://hotpocket.app/)
HotPocket v25.11.12 [${HOTPOCKET_BACKEND_IMAGE_ID}] (https://hotpocket.app/)
Copyright 2025-present by BTHLabs. All rights reserved. (https://bthlabs.pl/)
Licensed under Apache-2.0
EOF

View File

@@ -1,6 +1,6 @@
{
"name": "hotpocket-backend",
"version": "25.11.06",
"version": "25.11.12",
"description": "HotPocket Backend",
"main": "hotpocket_backend/apps/frontend/src/index.js",
"repository": "https://git.bthlabs.pl/tomekwojcik/hotpocket",

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "hotpocket-backend"
version = "25.11.06"
version = "25.11.12"
description = "HotPocket Backend"
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
license = "Apache-2.0"

View File

@@ -29,21 +29,45 @@ def mock_saves_process_save_task_apply_async(mocker: pytest_mock.MockerFixture,
@pytest.fixture
def payload():
def url_to_save():
return 'https://www.ziomek.dog/'
@pytest.fixture
def payload_with_text(url_to_save):
return {
'text': 'https://www.ziomek.dog/',
'text': url_to_save,
}
@pytest.fixture
def payload_with_url(url_to_save):
return {
'url': url_to_save,
}
@pytest.mark.parametrize(
'payload_fixture_name',
[
'payload_with_text',
'payload_with_url',
],
)
@pytest.mark.django_db
def test_ok(authenticated_client: Client,
payload,
def test_ok(payload_fixture_name,
request: pytest.FixtureRequest,
authenticated_client: Client,
account,
url_to_save,
mock_saves_process_save_task_apply_async: mock.Mock,
):
# Given
payload = request.getfixturevalue(payload_fixture_name)
# When
result = authenticated_client.post(
reverse('ui.integrations.android.share_sheet'),
reverse('ui.integrations.pwa.share_sheet'),
data=payload,
)
@@ -69,7 +93,7 @@ def test_ok(authenticated_client: Client,
SavesTestingService().assert_created(
pk=save_pk,
account_uuid=account.pk,
url=payload['text'],
url=url_to_save,
is_netloc_banned=False,
)
@@ -82,17 +106,17 @@ def test_ok(authenticated_client: Client,
@pytest.mark.django_db
def test_ok_netloc_banned(authenticated_client: Client,
payload,
payload_with_text,
account,
mock_saves_process_save_task_apply_async: mock.Mock,
):
# Given
payload['text'] = 'https://youtube.com/'
payload_with_text['text'] = 'https://youtube.com/'
# When
result = authenticated_client.post(
reverse('ui.integrations.android.share_sheet'),
data=payload,
reverse('ui.integrations.pwa.share_sheet'),
data=payload_with_text,
)
# Then
@@ -108,25 +132,25 @@ def test_ok_netloc_banned(authenticated_client: Client,
SavesTestingService().assert_created(
pk=save_pk,
account_uuid=account.pk,
url=payload['text'],
url=payload_with_text['text'],
is_netloc_banned=True,
)
@pytest.mark.django_db
def test_ok_reuse_save(authenticated_client: Client,
payload,
payload_with_text,
save_out,
account,
mock_saves_process_save_task_apply_async: mock.Mock,
):
# Given
payload['text'] = save_out.url
payload_with_text['text'] = save_out.url
# When
result = authenticated_client.post(
reverse('ui.integrations.android.share_sheet'),
data=payload,
reverse('ui.integrations.pwa.share_sheet'),
data=payload_with_text,
)
# Then
@@ -156,19 +180,19 @@ def test_ok_reuse_save(authenticated_client: Client,
@pytest.mark.django_db
def test_ok_reuse_association(authenticated_client: Client,
payload,
payload_with_text,
save_out,
account,
association_out,
mock_saves_process_save_task_apply_async: mock.Mock,
):
# Given
payload['text'] = save_out.url
payload_with_text['text'] = save_out.url
# When
result = authenticated_client.post(
reverse('ui.integrations.android.share_sheet'),
data=payload,
reverse('ui.integrations.pwa.share_sheet'),
data=payload_with_text,
)
# Then
@@ -182,18 +206,18 @@ def test_ok_reuse_association(authenticated_client: Client,
@pytest.mark.django_db
def test_ok_reuse_other_account_save(authenticated_client: Client,
payload,
payload_with_text,
other_account_save_out,
account,
mock_saves_process_save_task_apply_async: mock.Mock,
):
# Given
payload['text'] = other_account_save_out.url
payload_with_text['text'] = other_account_save_out.url
# When
result = authenticated_client.post(
reverse('ui.integrations.android.share_sheet'),
data=payload,
reverse('ui.integrations.pwa.share_sheet'),
data=payload_with_text,
)
# Then
@@ -214,18 +238,18 @@ def test_ok_reuse_other_account_save(authenticated_client: Client,
@pytest.mark.django_db
def test_ok_dont_process_reused_processed_save(authenticated_client: Client,
payload,
payload_with_text,
processed_save_out,
account,
mock_saves_process_save_task_apply_async: mock.Mock,
):
# Given
payload['text'] = processed_save_out.url
payload_with_text['text'] = processed_save_out.url
# When
_ = authenticated_client.post(
reverse('ui.integrations.android.share_sheet'),
data=payload,
reverse('ui.integrations.pwa.share_sheet'),
data=payload_with_text,
)
# Then
@@ -234,19 +258,19 @@ def test_ok_dont_process_reused_processed_save(authenticated_client: Client,
@pytest.mark.django_db
def test_invalid_all_empty(authenticated_client: Client,
payload,
payload_with_text,
mock_saves_process_save_task_apply_async: mock.Mock,
):
# Given
effective_payload = {
key: ''
for key
in payload.keys()
in payload_with_text.keys()
}
# When
result = authenticated_client.post(
reverse('ui.integrations.android.share_sheet'),
reverse('ui.integrations.pwa.share_sheet'),
data=effective_payload,
)
@@ -269,7 +293,7 @@ def test_invalid_all_missing(authenticated_client: Client,
# When
result = authenticated_client.post(
reverse('ui.integrations.android.share_sheet'),
reverse('ui.integrations.pwa.share_sheet'),
data=effective_payload,
)
@@ -285,12 +309,12 @@ def test_invalid_all_missing(authenticated_client: Client,
@pytest.mark.django_db
def test_inactive_account(inactive_account_client: Client,
payload,
payload_with_text,
):
# When
result = inactive_account_client.get(
reverse('ui.integrations.android.share_sheet'),
data=payload,
reverse('ui.integrations.pwa.share_sheet'),
data=payload_with_text,
)
# Then
@@ -302,8 +326,8 @@ def test_inactive_account(inactive_account_client: Client,
(
'next',
reverse(
'ui.integrations.android.share_sheet',
query=payload,
'ui.integrations.pwa.share_sheet',
query=payload_with_text,
),
),
],
@@ -314,12 +338,12 @@ def test_inactive_account(inactive_account_client: Client,
@pytest.mark.django_db
def test_anonymous(client: Client,
payload,
payload_with_text,
):
# When
result = client.get(
reverse('ui.integrations.android.share_sheet'),
data=payload,
reverse('ui.integrations.pwa.share_sheet'),
data=payload_with_text,
)
# Then
@@ -331,8 +355,8 @@ def test_anonymous(client: Client,
(
'next',
reverse(
'ui.integrations.android.share_sheet',
query=payload,
'ui.integrations.pwa.share_sheet',
query=payload_with_text,
),
),
],

View File

@@ -20,5 +20,5 @@ def test_ok(client: Client, settings):
assert payload['short_name'] == settings.SITE_SHORT_TITLE
assert payload['start_url'] == f"http://testserver{reverse('ui.associations.browse')}"
assert payload['share_target']['action'] == (
f"http://testserver{reverse('ui.integrations.android.share_sheet')}"
f"http://testserver{reverse('ui.integrations.pwa.share_sheet')}"
)

View File

@@ -1,6 +1,6 @@
{
"name": "hotpocket-extension",
"version": "25.11.06",
"version": "25.11.12",
"description": "HotPocket Extension",
"main": "src/index.js",
"repository": "https://git.bthlabs.pl/tomekwojcik/hotpocket",

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "hotpocket-extension"
version = "25.11.06"
version = "25.11.12"
description = "HotPocket Extension"
authors = ["Tomek Wójcik <contact@bthlabs.pl>"]
license = "Apache-2.0"

View File

@@ -13,7 +13,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover,user-scalable=no">
<meta name="generator" content="pl.bthlabs.HotPocket.Extension@v25.11.06">
<meta name="generator" content="pl.bthlabs.HotPocket.Extension@v25.11.12">
<meta name="theme-color" content="#2b3035"/>
<title>HotPocket by BTHLabs</title>
<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,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">
@@ -79,7 +79,7 @@ body, html {
</div>
<p class="mb-0 mt-2 text-center text-muted ui-uname">
<span>
<a href="https://hotpocket.app/" target="_blank" rel="noopener noreferer">HotPocket by BTHLabs</a> v25.11.06
<a href="https://hotpocket.app/" target="_blank" rel="noopener noreferer">HotPocket by BTHLabs</a> v25.11.12
</span>
<br>
<span>Copyright &copy; 2025-present by BTHLabs. All rights reserved.</span>

View File

@@ -3,7 +3,7 @@
"default_locale": "en",
"name": "__MSG_extension_name__",
"description": "__MSG_extension_description__",
"version": "25.11.06",
"version": "25.11.12",
"icons": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",