mirror of
https://codeberg.org/vlw/vlw.se.git
synced 2025-09-13 21:13:40 +02:00
This PR features a lot of text revisions, updated references to GitHub with Codeberg and more. Reviewed-on: https://codeberg.org/vlw/vlw.se/pulls/4 Co-authored-by: Victor Westerlund <victor.vesterlund@gmail.com> Co-committed-by: Victor Westerlund <victor.vesterlund@gmail.com>
136 lines
No EOL
5.6 KiB
PHP
136 lines
No EOL
5.6 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("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("assets/media/icons/email.svg") ?>
|
|
<p>e-mail</p>
|
|
</social></a>
|
|
<a href="https://mastodon.social/@vlwone"><social>
|
|
<?= VV::embed("assets/media/icons/mastodon.svg") ?>
|
|
<p>mastodon</p>
|
|
</social></a>
|
|
<a href="https://web.libera.chat/#vlw.se"><social>
|
|
<?= VV::embed("assets/media/icons/libera.svg") ?>
|
|
<p>libera.chat</p>
|
|
</social></a>
|
|
</section>
|
|
<?= VV::embed("assets/media/line.svg") ?>
|
|
<section class="pgp">
|
|
<?= VV::embed("assets/media/icons/pin.svg") ?>
|
|
<h3>encrypt your message with PGP</h3>
|
|
<p>Please consider encrypting your message with my PGP key, even if your message doesn't contain anything sensitive. The key is also available via <a href="https://wiki.gnupg.org/WKD" target="_blank" rel="noopener noreferer">WKD</a>, and is listed on the <a href="https://keys.openpgp.org/search?q=victor%40vlw.se" target="_blank" rel="noopener noreferer">openPGP key server</a> for victor@vlw.se.</p>
|
|
<p>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>Fingerprint for info@vlw.se</p>
|
|
<p>For reference only, please don't send personal emails to this address</p>
|
|
<p><strong class="fingerprint">DC603DA049903D707B7F1DB39AF727FB576F5A00</strong></p>
|
|
</section>
|
|
<?= VV::embed("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("assets/js/pages/contact") ?></script>
|