- Implemented.

Replaced polling with a single queued cursor worker, timeout recovery, 
backoff, deduplication, chronological insertion, and capped DOM history 
in cyberchat-v4.js.
Removed Groups UI, API, configuration, tier features, admin controls, 
and archive exposure.
Legacy group records remain stored but inaccessible.
Added configurable polling limits in config.json.
This commit is contained in:
Ty Clifford
2026-06-08 23:28:42 -04:00
parent ef7a9a330f
commit ccdbc47642
12 changed files with 368 additions and 667 deletions
+2 -33
View File
@@ -1,15 +1,9 @@
<?php
function handleAdminPlatformAction(string $action): ?string {
if ($action === 'save_group_availability') {
setConfigValues(['groups.enabled' => !empty($_POST['groups_enabled'])]);
return 'Group availability saved.';
}
if ($action === 'save_platform_services') {
setConfigValues([
'subscriptions.enabled' => !empty($_POST['subscriptions_enabled']),
'groups.enabled' => !empty($_POST['groups_enabled']),
'mailgun.api_key' => trim((string)($_POST['mailgun_api_key'] ?? '')),
'mailgun.domain' => trim((string)($_POST['mailgun_domain'] ?? '')),
'mailgun.from' => trim((string)($_POST['mailgun_from'] ?? '')),
@@ -33,7 +27,7 @@ function handleAdminPlatformAction(string $action): ?string {
$db = getDB();
$plans = $_POST['plans'] ?? [];
$boolFeatures = [
'voice_messages', 'recording_status', 'auto_voice_send', 'auto_voice_play', 'groups_available', 'username_color',
'voice_messages', 'recording_status', 'auto_voice_send', 'auto_voice_play', 'username_color',
'text_export', 'voice_archive', 'voice_export', 'email_2fa',
];
$db->beginTransaction();
@@ -62,7 +56,6 @@ function handleAdminPlatformAction(string $action): ?string {
foreach ($boolFeatures as $key) {
$upsertFeature->execute([$id, $key, json_encode(!empty($plan['features'][$key]))]);
}
$upsertFeature->execute([$id, 'group_member_limit', json_encode(max(2, min(100, (int)($plan['features']['group_member_limit'] ?? 2))))]);
$upsertFeature->execute([$id, 'text_archive_days', json_encode(max(30, min(3650, (int)($plan['features']['text_archive_days'] ?? 30))))]);
}
$db->commit();
@@ -87,8 +80,7 @@ function handleAdminPlatformAction(string $action): ?string {
$id = (int)$db->lastInsertId();
$features = [
'voice_messages' => true, 'recording_status' => false, 'auto_voice_send' => false,
'auto_voice_play' => false, 'groups_available' => false,
'group_member_limit' => 2, 'username_color' => false, 'text_archive_days' => 30,
'auto_voice_play' => false, 'username_color' => false, 'text_archive_days' => 30,
'text_export' => true, 'voice_archive' => false, 'voice_export' => false, 'email_2fa' => false,
];
$insert = $db->prepare("INSERT INTO plan_features (plan_id,feature_key,value_json) VALUES (?,?,?)");
@@ -120,7 +112,6 @@ function renderAdminPlatformTab(): void {
'visits_24h' => (int)$db->query("SELECT COUNT(*) FROM visitor_events WHERE event_type='visit' AND created_at>" . (time() - 86400))->fetchColumn(),
'unique_24h' => (int)$db->query("SELECT COUNT(DISTINCT ip_hash) FROM visitor_events WHERE created_at>" . (time() - 86400))->fetchColumn(),
'paid' => (int)$db->query("SELECT COUNT(*) FROM users WHERE subscription_status IN ('active','trialing','past_due')")->fetchColumn(),
'groups' => (int)$db->query("SELECT COUNT(*) FROM chat_groups")->fetchColumn(),
];
$events = $db->query("SELECT event_type,COUNT(*) AS total FROM visitor_events
WHERE created_at>" . (time() - 2592000) . " GROUP BY event_type ORDER BY total DESC")->fetchAll();
@@ -136,7 +127,6 @@ function renderAdminPlatformTab(): void {
<div class="stat-card green"><div class="stat-num"><?= $stats['visits_24h'] ?></div><div class="stat-label">Visits / 24h</div></div>
<div class="stat-card blue"><div class="stat-num"><?= $stats['unique_24h'] ?></div><div class="stat-label">Unique / 24h</div></div>
<div class="stat-card violet"><div class="stat-num"><?= $stats['paid'] ?></div><div class="stat-label">Paid Subscribers</div></div>
<div class="stat-card orange"><div class="stat-num"><?= $stats['groups'] ?></div><div class="stat-label">Private Groups</div></div>
</div>
<form method="post">
@@ -146,10 +136,6 @@ function renderAdminPlatformTab(): void {
<div class="panel-body"><label class="cb-row"><input type="checkbox" name="subscriptions_enabled" <?= getConfigVal('subscriptions.enabled', true) ? 'checked' : '' ?>>
<span>Allow and display new subscriptions. When off, existing subscribers can still manage billing.</span></label></div></div>
<div class="panel"><div class="panel-head"><span class="panel-title">// GROUP AVAILABILITY</span></div>
<div class="panel-body"><label class="cb-row"><input type="checkbox" name="groups_enabled" <?= groupsEnabled() ? 'checked' : '' ?>>
<span>Enable private groups. When off, group navigation and channels are hidden while existing group data is preserved.</span></label></div></div>
<div class="panel"><div class="panel-head"><span class="panel-title">// MAILGUN</span></div><div class="panel-body">
<div class="form-row3">
<div class="field"><label>API Key</label><input type="password" name="mailgun_api_key" value="<?= esc(getConfigVal('mailgun.api_key', '')) ?>"></div>
@@ -204,23 +190,6 @@ function renderAdminPlatformTab(): void {
<div class="field"><label>Sort Order</label><input type="number" name="plans[<?= $plan['id'] ?>][sort_order]" value="<?= (int)$plan['sort_order'] ?>"></div>
</div>
<label class="cb-row"><input type="checkbox" name="plans[<?= $plan['id'] ?>][active]" <?= $plan['active'] ? 'checked' : '' ?>><span>Plan active</span></label>
<div style="border:1px solid var(--bd2);border-radius:4px;padding:12px;margin:12px 0">
<div class="panel-title" style="margin-bottom:10px">// GROUPS</div>
<div class="form-row">
<label class="cb-row" style="align-self:center;margin:0">
<input type="checkbox" name="plans[<?= $plan['id'] ?>][features][groups_available]"
<?= !empty($plan['features']['groups_available']) ? 'checked' : '' ?>>
<span><strong>Enable groups for this tier</strong></span>
</label>
<div class="field">
<label>Maximum People Per Group</label>
<input type="number" min="2" max="100" step="1"
name="plans[<?= $plan['id'] ?>][features][group_member_limit]"
value="<?= max(2, (int)($plan['features']['group_member_limit'] ?? 2)) ?>">
<div class="dim" style="margin-top:5px">Minimum 2, including the group owner. Use the toggle to disable groups; no 0 value is needed.</div>
</div>
</div>
</div>
<div class="form-row3">
<?php foreach ($featureKeys as $key): ?>
<?php if ($key === 'text_archive_days'): ?>