68 Commits

Author SHA1 Message Date
Alcea 5cd51f6d1e Add files via upload 2025-07-20 19:57:28 +02:00
Alcea 524c4c80b4 Add files via upload 2025-07-20 19:03:06 +02:00
Alcea f5b9e8f411 Add files via upload 2025-07-20 16:41:05 +02:00
Alcea 4d1afd6e72 Add files via upload
Read all profileinfo + ava from profileinfo.json
2025-07-20 15:35:22 +02:00
Alcea 30de670dce Add files via upload
Set indexable to true too

    $profileObject = [
        '@context' => 'https://www.w3.org/ns/activitystreams',
        'id' => "$baseUrl/$username",
        'type' => 'Person',
        'name' => 'Alcea Bot',
        'discoverable'  => true,  // Update the discoverable field
        'locked'        => false,
        'bot'           => false,
        // Add any other fields you need to update
        'preferredUsername' => $username,
        'summary' => formatDescriptionLinks($description),
        'icon' => [
            'type' => 'Image',
            'mediaType' => 'image/gif',
            'url' => $imageUrl,
        ],
        'inbox' => "$baseUrl/$username/inbox",
        'outbox' => "$baseUrl/$username/outbox",
        'followers' => "$baseUrl/$username/followers",
        'publicKey' => [
            'id' => "$baseUrl/$username#main-key",
            'owner' => "$baseUrl/$username",
            'publicKeyPem' => @file_get_contents(__DIR__ . '/public.pem'),
'publicKeyPem' => @file_get_contents(__DIR__ . '/public.pem'),
        ],
        'fields' => $fields,
        'discoverability' => 'public', // <-- Here is the key for discoverability
        'indexable' => 'true',
    ];
2025-07-20 14:17:59 +02:00
Alcea 40222cd970 Add files via upload
Post php to post directly without update sync
2025-07-20 14:03:22 +02:00
Alcea a2856a6d33 Add files via upload
Router Revamp to serve tsgs and emoji in tags
----

if (preg_match('/^\/' . $username . '\/status\/([a-z0-9\-]+)$/', $uri, $m)) {
    $postId = $m[1];
    $post   = null; $date = ''; $hash = '';
    foreach ($data as $entry)
        foreach ($entry as $d => $c)
            if ("$d-" . substr(md5($c['value']), 0, 8) === $postId) {
                $post = $c; $date = $d; $hash = substr(md5($c['value']), 0, 8); break 2;
            }
    if (!$post) {
        http_response_code(404);
        echo "Not found";
        exit;
    }

    // Construct noteId
    $noteId = "$baseUrl/$username/status/{$date}-$hash";

    // Extract content
    $content = $post['value'];

    // Prepare tags (hashtags, mentions, emoji tags)
    $tags = [];
    $emojiTags = [];
    $hashtags = [];
    $mentions = [];

    // Extract hashtags: #hashtag
    preg_match_all('/#(\w+)/', $content, $hashtags);
    foreach ($hashtags[1] as $hashtag) {
        $tags[] = [
            "type" => "Hashtag",
            "name" => "#$hashtag",
            "href" => "$baseUrl/tags/$hashtag"
        ];
    }

    // Extract mentions: @username
    preg_match_all('/@(\w+)/', $content, $mentions);
    foreach ($mentions[1] as $mention) {
        // Not directly used in tags, but can be added if needed
    }

    // Extract emoji tags: :emoji:
    preg_match_all('/:([\w\+\-]+):/', $content, $emojiTags);
    foreach ($emojiTags[1] as $emoji) {
        // Assuming emoji images are stored on a path like "/z_files/emojis/{emoji}.gif"
        $tags[] = [
            "type" => "Emoji",
            "name" => ":$emoji:",
            "icon" => [
                "type" => "Image",
                "mediaType" => "image/gif",
                "url" => "$baseUrl/z_files/emojis/$emoji.gif"
            ]
        ];
    }

    // Determine if client accepts JSON
    $accept = $_SERVER['HTTP_ACCEPT'] ?? '';
    if (str_contains($accept, 'application/activity+json') || str_contains($accept, 'application/ld+json')) {
        header('Content-Type: application/activity+json');
        echo json_encode([
            '@context'     => [
                'https://www.w3.org/ns/activitystreams',
                [
                    'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
                    'toot' => 'http://joinmastodon.org/ns#',
                    'featured' => [
                        '@id' => 'toot:featured',
                        '@type' => '@id'
                    ]
                ]
            ],
            'id'           => $noteId,
            'type'         => 'Note',
            'published'    => date(DATE_ATOM, strtotime($date)),
            'attributedTo' => "$baseUrl/$username",
            'to'           => ['https://www.w3.org/ns/activitystreams#Public'],
            'content'      => $content,
            'contentMap'   => [
                'und' => $content,
                'html' => nl2br($content) // Convert newlines to <br> for HTML
            ],
            'tag'          => $tags,
        ], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
        exit;
    }

    // Otherwise, return an HTML redirect after 1 second
    header('Content-Type: text/html');
    $redirectUrl = "https://alceawis.com#" . $noteId;
    echo <<<HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Redirecting…</title>
    <meta http-equiv="refresh" content="1; url=$redirectUrl">
</head>
<body>
    <p>Redirecting to <a href="$redirectUrl">$redirectUrl</a>…</p>
</body>
</html>
HTML;
    exit;
}


if ($uri === "/$username/followers" || $uri === "/$username/followers/") {
    header('Content-Type: application/activity+json');
    header('Vary: Accept');
    $followers = file_exists(__DIR__ . '/followers.json') ? json_decode(file_get_contents(__DIR__ . '/followers.json'), true) : [];
    echo json_encode(['@context'=>'https://www.w3.org/ns/activitystreams','id'=>"$baseUrl/$username/followers",'type'=>'OrderedCollection','totalItems'=>count($followers),'orderedItems'=>$followers], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
    exit;
}
2025-07-20 12:23:17 +02:00
Alcea 30d1459100 Add files via upload 2025-07-20 02:44:06 +02:00
Alcea b1266304f1 Add files via upload
<button class="json-btn" data-json-url="${post.id}" style="padding:5px 10px; cursor:pointer;background: rgba(255, 105, 180, 0.7); border: none;border-radius: 12px;color: white;font-weight: bold;transition: background 0.3s ease;">  Show JSON</button>

<!--Show--Json-->
<script>
  (function() {
    const modalHTML = `
      <div id="jsonModal" style="
        display:none;
        position:fixed;
        top:0; left:0;
        width:100vw; height:100vh;
        background:rgba(0,0,0,0.5);
        justify-content:center;
        align-items:center;
        z-index:1000;
      ">
        <div style="
          background:#fff;
          padding:1em;
          max-width:90%;
          max-height:80vh;
          overflow:auto;
          border-radius:5px;
          position:relative;
          width: 90%;
          max-width: 600px;
        " onclick="event.stopPropagation()">
  <button id="copyJsonBtn" style="
  position:absolute; top:10px; right:10px;
  padding:5px 10px; cursor:pointer;
  background: rgba(255, 105, 180, 0.7); /* pink with 70% opacity */
  border: none;
  border-radius: 12px; /* rounded corners */
  color: white;
  font-weight: bold;
  transition: background 0.3s ease;
" disabled>Copy</button>
          <pre id="jsonContent" style="
            white-space:pre-wrap;
            font-size:0.85em;
            margin-top: 40px;
            user-select: text;
          "></pre>
        </div>
      </div>
    `;
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = modalHTML;
    document.body.appendChild(tempDiv.firstElementChild);
    const copyBtn = document.getElementById('copyJsonBtn');
    const content = document.getElementById('jsonContent');
    copyBtn.addEventListener('click', () => {
      if (copyBtn.disabled) return;
      const textToCopy = content.textContent;
      if (!textToCopy) return;
      navigator.clipboard.writeText(textToCopy)
        .then(() => {
          copyBtn.textContent = 'Copied!';
          setTimeout(() => copyBtn.textContent = 'Copy', 1500);
        })
        .catch(() => {
          copyBtn.textContent = 'Failed to copy';
          setTimeout(() => copyBtn.textContent = 'Copy', 1500);
        });
    });
  })();
  document.addEventListener('click', async (e) => {
    const modal = document.getElementById('jsonModal');
    const copyBtn = document.getElementById('copyJsonBtn');
    const content = document.getElementById('jsonContent');
    if (e.target === modal) {
      modal.style.display = 'none';
      return;
    }
    if (e.target.matches('.json-btn')) {
      const url = e.target.getAttribute('data-json-url');
      if (!url) {
        content.textContent = ' Invalid JSON URL.';
        modal.style.display = 'flex';
        copyBtn.disabled = true;
        return;
      }
      content.textContent = 'Loading...';
      modal.style.display = 'flex';
      copyBtn.disabled = true;
      try {
        const res = await fetch(url, { headers: { 'Accept': 'application/activity+json' } });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data = await res.json();
        content.textContent = JSON.stringify(data, null, 2);
        copyBtn.disabled = false;
        copyBtn.textContent = 'Copy';
      } catch (err) {
        content.textContent = ` Failed to load JSON:\n${err.message}`;
        copyBtn.disabled = true;
        copyBtn.textContent = 'Copy';
      }
    }
  });
</script>
2025-07-19 23:38:06 +02:00
Alcea 441d6307fe Add files via upload
Pull profile info from json
(Attempted some fixes for shorthand remote server emoj rendering suchas 🤣 :RJ_RedJohn_TheMentalist: :confused_dog: 

But alas...
https://alceawis.com/alceawis/status/20250719-e29c54df
https://alceawis.com/alceawis/status/20250719-1ab45011
2025-07-19 22:32:48 +02:00
Alcea 77456cc46a Add files via upload 2025-07-19 17:13:01 +02:00
Alcea fc27e71492 Add files via upload
Added Fediverse Reply Button & Modal
2025-07-19 16:18:20 +02:00
Alcea cedbc339ee Add files via upload
Add instance perma link via

        postElement.appendChild(quoteBlock);
}


//link2acws
// Function to decode surrogate pairs and Unicode escapes from JSON string literal
function decodeUnicodeEscapes(str) {
    return str.replace(/\\u([\dA-Fa-f]{4})/g, (_, hex) =>
        String.fromCharCode(parseInt(hex, 16))
    );
}

if (value.includes("•acws")) {
    // Step 1: decode the literal Unicode escapes (\ud809\udc2b) to real characters
    const decodedValue = decodeUnicodeEscapes(value);
    const formattedValue = decodedValue.replace(/𒐫(.*?)𒐫/g, '<blockquote>$1</blockquote>');

    const dateClean = date.replace(/-/g, '');
    const hash = CryptoJS.MD5(formattedValue).toString().substring(0, 8);
    const permalink = `https://alceawis.com/alceawis/status/${dateClean}-${hash}`;

    // Step 4: create and append link
    const link = document.createElement('a');
    link.href = permalink;
    link.target = "_blank";
    link.textContent = 'Permalink';
    link.classList.add('btn2');
    postElement.appendChild(link);
}





postElement.appendChild(hashtagsElement);
2025-07-19 15:49:47 +02:00
Alcea 41d0596d66 Add files via upload
Replace status redirect handler ro resirect to instsnce ststus AND serve json for 2 seconds

if (preg_match('/^\/' . $username . '\/status\/([a-z0-9\-]+)$/', $uri, $m)) {
    $postId = $m[1];
    $post   = null; $date = ''; $hash = '';
    foreach ($data as $entry)
        foreach ($entry as $d => $c)
            if ("$d-" . substr(md5($c['value']),0,8) === $postId) {
                $post = $c; $date = $d; $hash = substr(md5($c['value']),0,8); break 2;
            }
    if (!$post) {
        http_response_code(404);
        echo "Not found";
        exit;
    }

    $noteId = "$baseUrl/$username/status/{$date}-$hash";

    // Determine if client accepts JSON
    $accept = $_SERVER['HTTP_ACCEPT'] ?? '';
    if (str_contains($accept, 'application/activity+json') || str_contains($accept, 'application/ld+json')) {
        header('Content-Type: application/activity+json');
        echo json_encode([
            '@context'     => 'https://www.w3.org/ns/activitystreams',
            'id'           => $noteId,
            'type'         => 'Note',
            'published'    => date(DATE_ATOM, strtotime($date)),
            'attributedTo' => "$baseUrl/$username",
            'to'           => ['https://www.w3.org/ns/activitystreams#Public'],
            'content'      => $post['value'],
            'contentMap'   => ['und' => $post['value']],
        ], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
        exit;
    }

    // Otherwise, return an HTML redirect after 1 second
    header('Content-Type: text/html');
    $redirectUrl = "https://alceawis.com#" . $noteId;
    echo <<<HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Redirecting…</title>
    <m eta ht.  tp-equiv="refresh" content="1; url=$re. directUrl">
</head>
<body>
    <p>Redirecting to <a href="$redirectUrl">$redirectUrl</a>…</p>
</body>
</html>
HTML;
    exit;
}
2025-07-19 09:30:59 +02:00
Alcea 7226b2c6a2 Add files via upload
Sending Reply notifications works now !
--------------

/* ---------- build outbox ---------- */


$lastNoteId = null;

foreach ($data as $entry) {
    foreach ($entry as $date => $content) {
        $hash = substr(md5($content['value']), 0, 8);
        $text = formatEmojis($content['value']);

        $inReplyTo = null;
        $mentionTag = null;
        $mentionAcct = null;

        if (preg_match('/💬(https?:\/\/[^\s💬]+)💬/', $text, $match)) {
            $inReplyTo = $match[1];
            $lines = explode("\n", $text);
            array_shift($lines);
            $text = implode("\n", $lines);
        }

        // Extract hashtags
        $hashtags = array_filter(array_map('trim', explode(',', $content['hashtags'] ?? '')));

        // Handle @mention if replying to someone
        if ($inReplyTo && preg_match('~https?://([^/]+)/@([a-zA-Z0-9_]+)~', $inReplyTo, $matches)) {
            $mentionDomain = $matches[1];
            $mentionUser = $matches[2];
            $mentionAcct = "$mentionUser@$mentionDomain";
            $mentionUrl = "https://$mentionDomain/@$mentionUser";
            $mentionText = "@$mentionAcct ";

            if (strpos($text, $mentionText) !== 0) {
                $text = $mentionText . $text;
            }

            // Create Mention tag object
            $mentionTag = [
                'type' => 'Mention',
                'href' => $mentionUrl,
                'name' => "@$mentionAcct"
            ];
        }

        // Format quotes and links
        $quotedText = formatQuotes($text);
        $htmlText = preg_replace(
            '~(https?://[^\s<]+)~i',
            '<a href="$1" target="_blank" rel="nofollow noopener noreferrer">$1</a>',
            $quotedText
        );

        // Convert hashtags to tag links
        $htmlText = preg_replace_callback('/#([\w-]+)/', function($matches) use ($domain) {
            $tag = $matches[1];
            $url = "https://$domain/tags/" . urlencode($tag);
            return "<a href=\"$url\" rel=\"tag nofollow noopener noreferrer\">#" . htmlspecialchars($tag) . "</a>";
        }, $htmlText);

        $htmlText = nl2br($htmlText);

        // Build hashtag tag objects
        $tags = array_map(function($tag) use ($domain) {
            return [
                'type' => 'Hashtag',
                'name' => "#$tag",
                'href' => "https://$domain/tags/$tag"
            ];
        }, $hashtags);

        // Extract emoji shortcodes and create tag objects
        preg_match_all('/:([a-zA-Z0-9_]+):/', $content['value'], $emojiMatches);
        foreach ($emojiMatches[1] as $shortcode) {
            $tags[] = [
                'type' => 'Emoji',
                'name' => ":$shortcode:",
                'icon' => [
                    'type' => 'Image',
                    'mediaType' => 'image/gif',
                    'url' => "https://$domain/z_files/emojis/$shortcode.gif"
                ]
            ];
        }

        // Add mention tag if applicable
        if ($mentionTag) {
            $tags[] = $mentionTag;
        }

        // Compose Note ID
        $noteId = "$baseUrl/$username/status/{$date}-$hash";

        // Build the Note object
        $note = [
            'id' => $noteId,
            'type' => 'Note',
            'published' => date(DATE_ATOM, strtotime($date)),
            'attributedTo' => "$baseUrl/$username",
            'to' => ['https://www.w3.org/ns/activitystreams#Public'],
            'content' => $htmlText,
            'contentMap' => [
                'und' => $text,
                'html' => $htmlText,
            ],
            'tag' => $tags,
        ];

        // Add inReplyTo if exists
        if ($inReplyTo) {
            $note['inReplyTo'] = $inReplyTo;
        }

        $outboxItems[] = $note;

        // Send activity only if not already pushed
        if (!in_array($noteId, $pushed)) {
            sendCreateActivity($note);
            $pushed[] = $noteId;
            file_put_contents($pushedFile, json_encode($pushed, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
        }
    }
}

// Log last pushed note
if (!empty($pushed)) {
    $lastPushedUrl = end($pushed);

    foreach ($outboxItems as $item) {
        if ($item['id'] === $lastPushedUrl) {
            $noteText = $item['contentMap']['und'] ?? '[No text]';
            $inReplyTo = $item['inReplyTo'] ?? 'None';

            if (!file_exists('outbox.log')) {
                file_put_contents('outbox.log', '');
            }

            $logEntry = sprintf(
                "[%s] New post created\nStatus URL: %s\nReply To: %s\nContent:\n%s\n\n",
                date('Y-m-d H:i:s'),
                $lastPushedUrl,
                $inReplyTo,
                $noteText
            );

            //file_put_contents('outbox.log', $logEntry, FILE_APPEND | LOCK_EX);
            break;
        }
    }
}
2025-07-19 00:02:23 +02:00
Alcea d6fea241fa Add files via upload
Reimplemented emoji array tags *phew*

foreach ($data as $entry) {
    foreach ($entry as $date => $content) {
        $hash = substr(md5($content['value']), 0, 8);
        $text = formatEmojis($content['value']);

        $inReplyTo = null;
        if (preg_match('/💬(https?:\/\/[^\s💬]+)💬/', $text, $match)) {
            $inReplyTo = $match[1];
            $lines = explode("\n", $text);
            array_shift($lines);
            $text = implode("\n", $lines);
        }

        $hashtags = array_filter(array_map('trim', explode(',', $content['hashtags'] ?? '')));
        //$escapedText = htmlspecialchars($text);
        //$quotedText = formatQuotes($escapedText);
        $quotedText = formatQuotes($text);
        $htmlText = preg_replace(
            '~(https?://[^\s<]+)~i',
            '<a href="$1" target="_blank" rel="nofollow noopener noreferrer">$1</a>',
            $quotedText
        );
        $htmlText = preg_replace_callback('/#([\w-]+)/', function($matches) use ($domain) {
            $tag = $matches[1];
            $url = "https://$domain/tags/" . urlencode($tag);
            return "<a href=\"$url\" rel=\"tag nofollow noopener noreferrer\">#" . htmlspecialchars($tag) . "</a>";
        }, $htmlText);
        $htmlText = nl2br($htmlText);
        $tags = array_map(function($tag) use ($domain) {
            return [
                'type' => 'Hashtag',
                'name' => "#$tag",
                'href' => "https://$domain/tags/$tag"
            ];
        }, $hashtags);

        preg_match_all('/:([a-zA-Z0-9_]+):/', $content['value'], $emojiMatches);
        $emojiTags = [];
        foreach ($emojiMatches[1] as $shortcode) {
            $emojiTags[] = [
                'type' => 'Emoji',
                'name' => ":$shortcode:",
                'icon' => [
                    'type' => 'Image',
                    'mediaType' => 'image/gif',
                    'url' => "https://$domain/z_files/emojis/$shortcode.gif"
                ]
            ];
        }

        $tags = array_merge($tags, $emojiTags);

        $noteId = "$baseUrl/$username/status/{$date}-$hash";

        $note = [
            'id' => $noteId,
            'type' => 'Note',
            'published' => date(DATE_ATOM, strtotime($date)),
            'attributedTo' => "$baseUrl/$username",
            'to' => ['https://www.w3.org/ns/activitystreams#Public'],
            'content' => $htmlText,
            'contentMap' => [
                'und' => $text,
                'html' => $htmlText,
            ],
            'tag' => $tags,
        ];

        if ($inReplyTo) {
            $note['inReplyTo'] = $inReplyTo;
        }

        $outboxItems[] = $note;

        if (!in_array($noteId, $pushed)) {
            sendCreateActivity($note);
            $pushed[] = $noteId;
            file_put_contents($pushedFile, json_encode($pushed, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
        }
    }
}
2025-07-18 04:19:10 +02:00
Alcea 1d172455eb Add files via upload 2025-07-17 12:24:29 +02:00
Alcea 91b153b721 Add files via upload
Allow replying if a 💬url💬 is in text body (to it)

/* ---------- build outbox ---------- */
foreach ($data as $entry) {
    foreach ($entry as $date => $content) {
        $hash      = substr(md5($content['value']), 0, 8);
        $text      = formatEmojis($content['value']);

        // 💬 inReplyTo detection
        $inReplyTo = null;
        if (preg_match('/💬\s*(https?:\/\/[^\s💬]+)\s*💬/', $text, $match)) {
            $inReplyTo = trim($match[1]);
            $text = trim(str_replace($match[0], '', $text)); // optionally remove 💬URL💬 from post
        }

        $hashtags  = array_filter(array_map('trim', explode(',', $content['hashtags'] ?? '')));
        $quoted    = formatQuotes($text);
        $htmlText  = preg_replace('~(https?://[^\s<]+)~i', '<a href="$1" target="_blank" rel="nofollow noopener noreferrer">$1</a>', $quoted);
        $htmlText  = preg_replace_callback('/#([\w-]+)/', fn($m) => "<a href=\"https://$GLOBALS[domain]/tags/" . urlencode($m[1]) . "\" rel=\"tag nofollow noopener noreferrer\">#" . htmlspecialchars($m[1]) . "</a>", $htmlText);
        $htmlText  = nl2br($htmlText);

        $tags = array_map(fn($tag) => ['type'=>'Hashtag','name'=>"#$tag",'href'=>"https://$GLOBALS[domain]/tags/$tag"], $hashtags);

        preg_match_all('/:([a-zA-Z0-9_]+):/', $content['value'], $emo);
        foreach ($emo[1] as $sc)
            $tags[] = ['type'=>'Emoji','name'=>":$sc:",'icon'=>['type'=>'Image','mediaType'=>'image/gif','url'=>"https://$GLOBALS[domain]/z_files/emojis/$sc.gif"]];

        $noteId = "$baseUrl/$username/status/{$date}-$hash";

        $note = [
            'id'           => $noteId,
            'url'          => $noteId,
            'type'         => 'Note',
            'published'    => date(DATE_ATOM, strtotime($date)),
            'attributedTo' => "$baseUrl/$username",
            'to'           => ['https://www.w3.org/ns/activitystreams#Public'],
            'content'      => $htmlText,
            'contentMap'   => ['und' => $text,'html' => $htmlText],
            'tag'          => $tags,
            'locked'       => false,
            'bot'          => false,
            'discoverable' => true,
            'group'        => false,
            'manuallyApprovesFollowers' => false,
        ];

        if ($inReplyTo) {
            $note['inReplyTo'] = $inReplyTo;
        }

        $outboxItems[] = $note;

        if (!in_array($noteId, $pushed)) {
            sendCreateActivity($note);
            $pushed[] = $noteId;
        }
    }
}
file_put_contents($pushedFile, json_encode($pushed, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
2025-07-16 11:29:07 +02:00
Alcea 8d0f4d11bb Add files via upload 2025-07-16 01:41:59 +02:00
Alcea 51cb44529a Add files via upload
updateprofile.phpxwill now change discoverable:true
    $profileObject = [
        '@context' => 'https://www.w3.org/ns/activitystreams',
        'id' => "$baseUrl/$username",
        'type' => 'Person',
        'name' => 'Alcea Bot',
        'discoverable'  => true,  // Update the discoverable field
        'locked'        => false,
        'bot'           => false,
        // Add any other fields you need to update
        'preferredUsername' => $username,
        'summary' => formatDescriptionLinks($description),
        'icon' => [
            'type' => 'Image',
            'mediaType' => 'image/gif',
            'url' => $imageUrl,
        ],
2025-07-16 00:27:25 +02:00
Alcea 452fef3290 Add files via upload 2025-07-15 12:52:57 +02:00
Alcea 2315132d68 Add files via upload
Add time key to json for future ref
2025-07-15 12:02:00 +02:00
Alcea 89050347a4 Add files via upload
Force discoverability in posts
    'locked'        => false,
    'bot'           => false,
    'discoverable'  => true,
    'group'         => false,
2025-07-15 03:21:16 +02:00
Alcea 9c35de99c4 Add files via upload
Timekey for updatejson
2025-07-15 02:11:14 +02:00
Alcea 6e20ee73b3 Add files via upload 2025-07-15 01:33:27 +02:00
Alcea 90d02f346f Add files via upload
Instance endpoint
2025-07-14 10:11:30 +02:00
Alcea 65a22d963b Add files via upload 2025-07-14 09:53:08 +02:00
Alcea da241c40a7 Add files via upload
Compatibility for nodeinfo
2025-07-14 09:35:27 +02:00
Alcea 5ed9b492e8 Add files via upload 2025-07-14 09:34:57 +02:00
Alcea 53dc0d5107 Add files via upload
Allow direct mentions
2025-07-13 18:31:20 +02:00
Alcea 0e323e81fa Add files via upload
Tool to update remote user info
2025-07-13 16:27:55 +02:00
Alcea 96e40fd9d9 Add files via upload 2025-07-13 13:46:05 +02:00
Alcea 277a32248e Add files via upload 2025-07-13 12:54:01 +02:00
Alcea 44e86fb401 Add files via upload
Nested Replies
2025-07-13 12:31:14 +02:00
Alcea 92a759e5d2 Add files via upload
Personalized Timeline
2025-07-13 10:49:33 +02:00
Alcea 3ba1c057a5 Add files via upload 2025-07-13 09:57:16 +02:00
Alcea 224652dab8 Add files via upload 2025-07-13 08:16:52 +02:00
Alcea 3fe8752b3d Add files via upload
Better check when
return preg_replace('/𒐫(.*?)𒐫/u', '<blockquote>$1</blockquote>', $text);

to prevent posting just emoji to json

Added before after for user to confirm
2025-07-13 08:04:06 +02:00
Alcea 2ef091e148 Add files via upload
Only redirect status posts to renderer if direcrly from alceawis root domain
2025-07-13 07:49:40 +02:00
Alcea fe11e33f6d Add files via upload 2025-07-13 07:42:06 +02:00
Alcea 636ac2c446 Add files via upload 2025-07-12 22:58:20 +02:00
Alcea 822460d2cf Add files via upload 2025-07-12 21:23:41 +02:00
Alcea 7386500670 Add files via upload 2025-07-12 20:52:43 +02:00
Alcea d3376d5c6a Add files via upload 2025-07-12 17:00:57 +02:00
Alcea 5e802b33a3 Add files via upload 2025-07-12 15:49:18 +02:00
Alcea ca37cb4966 Add files via upload
Added interaction logging and a rudimentary notification system
2025-07-12 14:48:29 +02:00
Alcea 7a11bcb29c Add files via upload 2025-07-12 14:04:34 +02:00
Alcea bfceb1d47c Add files via upload
Added htmlspecialchars fix in quotes
2025-07-12 10:49:31 +02:00
Alcea d5289fc575 Add files via upload
Fixing users redirect to actual user with htaccess
Hope this won't break things...
2025-07-12 09:58:11 +02:00
Alcea 6f6a3db4d2 Add files via upload 2025-07-12 09:47:09 +02:00