mirror of
https://codeberg.org/vlw/vlw.se.git
synced 2025-09-13 21:13:40 +02:00
135 lines
No EOL
5.8 KiB
PHP
135 lines
No EOL
5.8 KiB
PHP
<?php
|
|
|
|
use Vegvisir\Path;
|
|
|
|
use VLW\Client\API;
|
|
use VLW\API\Endpoints;
|
|
|
|
use VLW\API\Databases\VLWdb\Models\Messages\MessagesModel;
|
|
|
|
require_once VV::root("src/client/API.php");
|
|
require_once VV::root("api/src/Endpoints.php");
|
|
|
|
require_once VV::root("api/src/databases/models/Messages/Messages.php");
|
|
|
|
// Connect to VLW API
|
|
$api = new API();
|
|
|
|
class Date extends DateTimeImmutable {
|
|
private const AVAILABLE_TO_HOUR = 16;
|
|
private const AVAILABLE_FROM_HOUR = 10;
|
|
|
|
private const REPLY_TIME_HOURS_AVAILABLE = 2;
|
|
|
|
public function __construct() {
|
|
// Set DateTime for configured timezone
|
|
parent::__construct("now", new DateTimeZone($_ENV["time"]["date_time_zone"]));
|
|
}
|
|
|
|
// Return current hour in 24-hour format
|
|
private function get_hour(): int {
|
|
return (int) $this->format("G");
|
|
}
|
|
|
|
// Returns true if current time is between available from and to hours
|
|
public function is_available(): bool {
|
|
return $this->get_hour() >= self::AVAILABLE_FROM_HOUR && $this->get_hour() < self::AVAILABLE_TO_HOUR;
|
|
}
|
|
|
|
public function get_estimated_reply_hours(): int {
|
|
// I'm available! Return the estimated reply time for that
|
|
if ($this->is_available()) {
|
|
return self::REPLY_TIME_HOURS_AVAILABLE;
|
|
}
|
|
|
|
$hour = $this->get_hour();
|
|
|
|
return $hour < self::AVAILABLE_FROM_HOUR
|
|
// Return hours past midnight until I become available (clamped to estimated reply hours)
|
|
? max(self::AVAILABLE_FROM_HOUR - $hour, self::REPLY_TIME_HOURS_AVAILABLE)
|
|
// Return hours before midnight until I become available (clamped to estimated reply hours)
|
|
: max(self::AVAILABLE_FROM_HOUR + (24 - $hour), self::REPLY_TIME_HOURS_AVAILABLE);
|
|
}
|
|
}
|
|
|
|
$date = new Date();
|
|
|
|
?>
|
|
<style><?= VV::css("public/assets/css/pages/contact") ?></style>
|
|
<section>
|
|
<h1>Let's chat!</h1>
|
|
<p>The best way to get in touch is definitely by email, or through the form on this page. The time in Sweden is <i><?= $date->format("h:i a") ?></i> right now, I am currently <?= $date->is_available() ? "available" : "not available" ?> and will hopefully reply in about <?= $date->get_estimated_reply_hours() ?> hours.</p>
|
|
</section>
|
|
<section class="social">
|
|
<a href="mailto:victor@vlw.se"><social>
|
|
<?= VV::embed("public/assets/media/icons/email.svg") ?>
|
|
<p>e-mail</p>
|
|
</social></a>
|
|
<a href="matrix:@vlw:vlw.se"><social>
|
|
<?= VV::embed("public/assets/media/icons/matrix.svg") ?>
|
|
<p>matrix</p>
|
|
</social></a>
|
|
<a href="https://web.libera.chat/#vlw.se"><social>
|
|
<?= VV::embed("public/assets/media/icons/libera.svg") ?>
|
|
<p>libera.chat</p>
|
|
</social></a>
|
|
</section>
|
|
<?= VV::embed("public/assets/media/line.svg") ?>
|
|
<section class="pgp">
|
|
<?= VV::embed("public/assets/media/icons/pin.svg") ?>
|
|
<h3>encrypt your message with PGP</h3>
|
|
<p>Encryption is great, don't let certain <a href="https://web.archive.org/web/https://www.chatcontrol.eu">short-sighted politicians</a> fool you into thinking encryption is only for criminals. I encourage you to encrypt your message with PGP so we can aid normalization of platform-agnostic encryption for everyone. My key is available via <a href="https://wiki.gnupg.org/WKD" target="_blank" rel="noopener noreferer">WKD</a>, and it's also listed on the <a href="https://keys.openpgp.org/search?q=victor%40vlw.se" target="_blank" rel="noopener noreferer">openPGP key server</a>.</p>
|
|
<p>Here's the fingerprint for victor@vlw.se<br><strong class="fingerprint">DCE987311CB5D2A252F58951D0AD730E1057DFC6</strong></p>
|
|
<div class="buttons">
|
|
<a href="https://keys.openpgp.org/vks/v1/by-fingerprint/DCE987311CB5D2A252F58951D0AD730E1057DFC6"><button class="inline solid">download ASC</button></a>
|
|
<a href="https://emailselfdefense.fsf.org/en/" target="_blank" rel="noopener noreferer"><button class="inline">email encryption guide</button></a>
|
|
</div>
|
|
</section>
|
|
<section class="center fade">
|
|
<p>And for reference, here is the fingerprint for my "non-personal" address info@vlw.se</p>
|
|
<p><strong class="fingerprint">DC603DA049903D707B7F1DB39AF727FB576F5A00</strong></p>
|
|
</section>
|
|
<?= VV::embed("public/assets/media/line.svg") ?>
|
|
|
|
<?php // Send message on POST request ?>
|
|
<?php if ($_SERVER["REQUEST_METHOD"] === "POST"): ?>
|
|
|
|
<?php
|
|
|
|
// Send message via API
|
|
$send = $api->call(Endpoints::MESSAGES->value)->post([
|
|
MessagesModel::EMAIL->value => $_POST[MessagesModel::EMAIL->value],
|
|
MessagesModel::MESSAGE->value => $_POST[MessagesModel::MESSAGE->value]
|
|
]);
|
|
|
|
?>
|
|
|
|
<?php if ($send->ok): ?>
|
|
<section class="form-message sent">
|
|
<h3>🙏 Message sent!</h3>
|
|
</section>
|
|
<?php else: ?>
|
|
<?php // Show response body from endpoint as error if request failed ?>
|
|
<section class="form-message error">
|
|
<h3>😟 Oh no, something went wrong</h3>
|
|
<p>Response from API:</p>
|
|
<pre><?= $send->output() ?></pre>
|
|
</section>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
|
|
<section class="form">
|
|
<form method="POST">
|
|
<input-group>
|
|
<label>your email (optional)</label>
|
|
<input type="email" name="<?= MessagesModel::EMAIL->value ?>" placeholder="nissehult@example.com" autocomplete="off"></input>
|
|
</input-group>
|
|
<input-group>
|
|
<label title="this field is required">your message (required)</label>
|
|
<textarea name="<?= MessagesModel::MESSAGE->value ?>" required placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed molestie dignissim mauris vel dignissim. Sed et aliquet odio, id egestas libero. Vestibulum ut dui a turpis aliquam hendrerit id et dui. Morbi eu tristique quam, sit amet dictum felis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac nibh a ex accumsan ullamcorper non quis eros. Nam at suscipit lacus. Nullam placerat semper sapien, vitae aliquet nisl elementum a. Duis viverra quam eros, eu vestibulum quam egestas sit amet. Duis lobortis varius malesuada. Mauris in fringilla mi. "></textarea>
|
|
</input-group>
|
|
<button class="inline solid">send</button>
|
|
</form>
|
|
</section>
|
|
|
|
<script><?= VV::js("public/assets/js/pages/contact") ?></script>
|