Profile now got filter for replies

This commit is contained in:
sørenpeter 2024-04-07 21:24:09 +02:00
parent c9f7d05017
commit 7ca2dc3793
10 changed files with 201 additions and 170 deletions

View file

@ -35,6 +35,7 @@ $routes = [
'/login' => 'login.php', '/login' => 'login.php',
'/logout' => 'logout.php', '/logout' => 'logout.php',
'/profile' => 'profile.php', '/profile' => 'profile.php',
'/replies' => 'replies.php',
'/gallery' => 'gallery.php', '/gallery' => 'gallery.php',
//'/profile/([a-zA-Z0-9_-]+)' => 'profile.php', //'/profile/([a-zA-Z0-9_-]+)' => 'profile.php',
'/conv/([a-zA-Z0-9]{7})' => 'conv.php', // matches only twtHash of exactly 7 alphanumeric characters '/conv/([a-zA-Z0-9]{7})' => 'conv.php', // matches only twtHash of exactly 7 alphanumeric characters

View file

@ -174,6 +174,35 @@ a.author {
color: var(--accent); color: var(--accent);
} }
.profile .filters a {
text-decoration: none;
font-weight: bold;
padding-right: 0.5rem;
}
.profile a.active {
color: var(--accent);
}
/* == Tag Cloud ===================== */
.tagcloud {
margin-top: 0.75rem;
border-top: thin solid var(--border);
padding: 0.2rem;
}
.tagcloud a,
.tagcloud a:visited {
text-decoration: none;
padding-right: 0.2rem;
line-height: 1;
color: var(--text-light);
}
.tagcloud a.active {
color: var(--accent);
}
/* === TIMELINE === */ /* === TIMELINE === */
@ -282,25 +311,6 @@ nav.pagnation {
border-radius: 0.25rem; border-radius: 0.25rem;
} }
/* == Tag Cloud ===================== */
.tagcloud {
margin-top: 0.75rem;
border-top: thin solid var(--border);
padding: 0.2rem;
}
.tagcloud a,
.tagcloud a:visited {
text-decoration: none;
padding-right: 0.2rem;
color: var(--text-light);
}
.tagcloud a.active {
color: red;
}
/* === FOOTER === */ /* === FOOTER === */
footer { footer {

View file

@ -122,6 +122,7 @@ function getImagesFromTwt(string $twtString) {
function getTagsFromTwt(string $twtString) { function getTagsFromTwt(string $twtString) {
//$pattern = '/(?<!\()\B#\w+(?!\))/iu'; //$pattern = '/(?<!\()\B#\w+(?!\))/iu';
$pattern = '/(?<=\B)#(\w+)/'; $pattern = '/(?<=\B)#(\w+)/';
//$pattern = "/\(#\w{7}\)/";
//$pattern = '/(?<=\s|^)#(\w+)/'; //$pattern = '/(?<=\s|^)#(\w+)/';
// TODO: Fix so it does not match with url#fragments (\B vs \s) // TODO: Fix so it does not match with url#fragments (\B vs \s)
// But for some reason this does not work: '/(?<!\()\s#\w+(?!\))/iu'; // But for some reason this does not work: '/(?<!\()\s#\w+(?!\))/iu';

View file

@ -1,67 +0,0 @@
<?php
// Search / filter on tags (or anything within a twt actually)
// Base on code from: https://social.dfaria.eu/search
if (!empty($_GET['search'])) {
$searchfor = $_GET['search'];
//$file = 'twtxt.txt';
//$contents = file_get_contents($url);
$pattern = preg_quote($searchfor, '/');
$pattern = "/^.*$pattern.*\$/mi";
// 1. filter $twts for maches containg search string
/*
$twts_filtered = array_filter($twts, function($twt) {
return preg_match($pattern, $twt->content);
});
echo "<pre>";
print_r($twts[1711985096]);
*/
$twts_filtered = [];
//print_r($twts_filtered);
// 2. Repalce original $twts with new $twts_filtered
//$twts = $twts_filtered
foreach ($twts as $twt) {
if (preg_match_all($pattern, $twt->content, $matches)) {
echo "<hr>";
print_r($twt);
/*
$date = preg_filter('/^(?<date>[^\t]+)\t(?<entry>.+)/', '\2', $matches[0]);
$entry = preg_filter('/^(?<date>[^\t]+)\t(?<entry>.+)/', '\1', $matches[0]);
foreach ($date as $i => $tw) {
$post[$tw] = $entry[$i];
}
$post = array_reverse($post);
$perpage = 10;
if(isset($_GET['start'])) $start = $_GET['start']; else $start = 0;
$numposts = count($post);
$post = array_slice($post, $start, $perpage);
echo "<hr>";
foreach ($post as $tw => $data) {
echo $tw;
echo "<hr>";
}
*/
}
}
}

View file

@ -8,37 +8,74 @@ if (!empty($_GET['profile'])) {
$profile = getTwtsFromTwtxtString($url); $profile = getTwtsFromTwtxtString($url);
$profileURL = $baseURL . '/?profile=' . $profile->mainURL; $profileURL = $baseURL . '/?profile=' . $profile->mainURL;
$textareaValue = "@<$profile->nick $profile->mainURL> "; $textareaValue = "@<$profile->nick $profile->mainURL> ";
// TODO: Move this to twtxt.php or base.php
// and make nav for general timeline to filter on posts vs. replies + all
// Filter posts vs. replies
$pattern = "/\(#\w{7}\)/";
$twt_replies = array_filter($twts, function ($twt) use ($pattern) {
return preg_match($pattern, $twt->originalTwtStr);
});
$twt_posts = array_filter($twts, function ($twt) use ($pattern) {
return !preg_match($pattern, $twt->originalTwtStr);
});
// Get active view/filter
$is_gallery = str_contains(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), "gallery");
$is_replies = str_contains(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), "replies");
if ($is_gallery) {
$posts_active = "";
$replies_active = "";
$gallery_artive = "class='active'";
} elseif ($is_replies) {
$twts = $twt_replies;
$posts_active = "";
$replies_active = "class='active'";
$gallery_artive = "";
} else {
$twts = $twt_posts;
$posts_active = "class='active'";
$replies_active = "";
$gallery_artive = "";
}
?> ?>
<div class="profile"> <div class="profile">
<a href="<?=$profile->avatar?>"> <a href="<?=$profile->avatar?>">
<img class="avatar" src="<?=$profile->avatar?>" onerror="this.onerror=null;this.src='<?= $baseURL ?>/media/default.png';"> <img class="avatar" src="<?=$profile->avatar?>" onerror="this.onerror=null;this.src='<?= $baseURL ?>/media/default.png';">
</a> </a>
<div> <div>
<a href="<?=$profileURL?>" class="author"> <a href="<?=$profileURL?>" class="author">
<strong><?=$profile->nick?></strong>@<?=parse_url($profile->mainURL, PHP_URL_HOST);?> <strong><?=$profile->nick?></strong>@<?=parse_url($profile->mainURL, PHP_URL_HOST);?>
</a> </a>
<p><?=$profile->description?></p> <p><?=$profile->description?></p>
<small> <small>
<a href="<?=$profileURL?>">Posts</a> | <span class="filters">
<!-- <a href="">Replies</a> | --> <a <?=$posts_active?> href="<?=$profileURL?>" >Posts</a>
<a href="<?=$baseURL?>/gallery?profile=<?=$profile->mainURL?>">Gallery</a> <a <?=$replies_active?> href="<?=$baseURL?>/replies?profile=<?=$profile->mainURL?>" >Replies</a>
<a <?=$gallery_artive?> href="<?=$baseURL?>/gallery?profile=<?=$profile->mainURL?>" >Gallery</a>
</span>
<span class="right"> <span class="right">
<!-- <a href="following.php">Following <?php echo count($twtFollowingList); ?></a> | --> <!-- <a href="following.php">Following <?php echo count($twtFollowingList); ?></a> | -->
<a target="_blank" href="<?=$profile->mainURL?>"><?=$profile->mainURL?></a> <a target="_blank" href="<?=$profile->mainURL?>"><?=$profile->mainURL?></a>
(<a href="https://yarn.social">How to follow</a>) (<a href="https://yarn.social">How to follow</a>)
</span> </span>
<div class="tagcloud"> <div class="tagcloud">
<?php include_once 'partials/tag_cloud.php'; ?> <?php include_once 'partials/tag_cloud.php'; ?>
</div> </div>
</small> </small>
</div> </div>

15
partials/search.php Normal file
View file

@ -0,0 +1,15 @@
<?php
// Search / filter on tags (or anything within a twt actually)
// Base on hash filter below and on code from: https://social.dfaria.eu/search
if (!empty($_GET['search'])) {
$search = $_GET['search'];
$pattern = preg_quote($search, '/');
$pattern = "/^.*$pattern.*\$/mi";
$twts = array_filter($twts, function ($twt) use ($pattern) {
return preg_match($pattern, $twt->content);
});
}

View file

@ -3,63 +3,75 @@
// Tagcloud for twtxt // Tagcloud for twtxt
// Base on code from: https://social.dfaria.eu/search // Base on code from: https://social.dfaria.eu/search
// if(empty($_GET['search'])) { // Add all tags to one array
foreach ($twts as $twt) {
$tag_array = getTagsFromTwt($twt->content);
// Add all tags to one array foreach ($tag_array as $tag) {
foreach ($twts as $twt) { $tags[] = $tag[0];
$tag_array = getTagsFromTwt($twt->content);
foreach ($tag_array as $tag) {
$tags[] = $tag[0];
}
} }
}
natcasesort($tags); natcasesort($tags);
$tag_count = array_count_values($tags); $tag_count = array_count_values($tags);
//arsort($tag_count, SORT_STRING); //arsort($tag_count, SORT_STRING);
//ksort($tag_count, SORT_STRING); //ksort($tag_count, SORT_STRING);
//strnatcasecmp($tag_count); //strnatcasecmp($tag_count);
$max_count = max($tag_count); $max_count = max($tag_count);
$min_font_size = 10; $min_font_size = 10;
$max_font_size = 30; $max_font_size = 30;
$num_intermediate_levels = 1; $num_intermediate_levels = 1;
$font_size_interval = ($max_font_size - $min_font_size) / ($num_intermediate_levels + 1); $font_size_interval = ($max_font_size - $min_font_size) / ($num_intermediate_levels + 1);
$uri = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; // Get current URI to keep the `?profile=URL` as the base for links to tags
$uri = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
foreach ($tag_count as $tag => $count) { // Remove existing `(?|&)search=word` params from base URI
$font_size = $min_font_size + ($count / $max_count) * $font_size_interval; // https://stackoverflow.com/a/4937540
$tag = str_replace('#', '', $tag); $uri = preg_replace('/.search=\w+&?/', '$1', $uri);
// Get active tag, if any
$active_tag = "";
if (!empty($_GET['search'])) {
$active_tag = $_GET['search'];
}
foreach ($tag_count as $tag => $count) {
$font_size = $min_font_size + ($count / $max_count) * $font_size_interval;
$tag = str_replace('#', '', $tag);
if ($tag === $active_tag) {
echo '<a href="'.$uri.'&search='.$tag.'" style="font-size: '.$font_size.'px;" class="active">#'. $tag .'</a> ';
} else {
echo '<a href="'.$uri.'&search='.$tag.'" style="font-size: '.$font_size.'px;">#'. $tag .'</a> '; echo '<a href="'.$uri.'&search='.$tag.'" style="font-size: '.$font_size.'px;">#'. $tag .'</a> ';
//echo '<a href="?search='.$tag.'">#'. $tag .' ('.$count.')</a> ';
} }
//echo '<a href="?search='.$tag.'">#'. $tag .' ('.$count.')</a> ';
}
// Detail/summary with top tags and solo tags // Detail/summary with top tags and solo tags
/* /*
$top_tags = array_filter($tag_count, function($val){return ($val>1);}); $top_tags = array_filter($tag_count, function($val){return ($val>1);});
$solo_tags = array_diff($tag_count, $top_tags); $solo_tags = array_diff($tag_count, $top_tags);
krsort($solo_tags, SORT_STRING); krsort($solo_tags, SORT_STRING);
echo "<details><summary> Tags: "; echo "<details><summary> Tags: ";
foreach ($top_tags as $tag => $count) { foreach ($top_tags as $tag => $count) {
$tag = str_replace('#', '', $tag); $tag = str_replace('#', '', $tag);
echo '<a href="?search='.$tag.'">#'.$tag.'</a> '; echo '<a href="?search='.$tag.'">#'.$tag.'</a> ';
} }
echo "</summary>"; echo "</summary>";
foreach ($solo_tags as $tag => $count) { foreach ($solo_tags as $tag => $count) {
$tag = str_replace('#', '', $tag); $tag = str_replace('#', '', $tag);
echo '<a href="?search='.$tag.'">#'.$tag.'</a> '; echo '<a href="?search='.$tag.'">#'.$tag.'</a> ';
} }
echo "</details>"; echo "</details>";
*/ */
// } else {
// echo "Showing posts with <code>".$_GET['search']."</code>";
// }

View file

@ -6,23 +6,7 @@
<?php }?> <?php }?>
--> -->
<?php <?php include_once 'partials/search.php'; ?>
// Search / filter on tags (or anything within a twt actually)
// Base on hash filter below and on code from: https://social.dfaria.eu/search
if (!empty($_GET['search'])) {
$search = $_GET['search'];
$pattern = preg_quote($search, '/');
$pattern = "/^.*$pattern.*\$/mi";
$twts = array_filter($twts, function ($twt) use ($pattern) {
return preg_match($pattern, $twt->content);
});
}
?>
<?php foreach ($twts as $twt) {?> <?php foreach ($twts as $twt) {?>
<article class="post-entry" id="<?=$twt->hash?>"> <article class="post-entry" id="<?=$twt->hash?>">

View file

@ -36,6 +36,7 @@ if (!empty($_GET['profile'])) { // Show twts for some user
?> ?>
<?php include_once 'partials/search.php'; ?>
<!-- PHP: GALLERY --> <!-- PHP: GALLERY -->
<div class="gallery"> <div class="gallery">

37
views/replies.php Normal file
View file

@ -0,0 +1,37 @@
<?php
require_once("partials/base.php");
$title = "Replies - ".$title;
include_once 'partials/header.php';
?>
<!-- PHP: PROFILE CARD -->
<?php
if (!empty($_GET['profile'])) { // Show twts for some user
$twtsURL = $_GET['profile'];
// TODO: Give a propper error if feed is not valid
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
die('Not a valid URL');
}
// $parsedTwtxtFile = getTwtsFromTwtxtString($twtsURL);
if (!is_null($parsedTwtxtFile)) {
$parsedTwtxtFiles[$parsedTwtxtFile->mainURL] = $parsedTwtxtFile;
include 'partials/profile.php';
}
} else {
// TODO: default to rendering the local users gallery, if no profile specified
//echo $profile->mainURL;;
//$twtsURL = $profile->mainURL; // correct URL for twtxt.txt
}
?>
<!-- PHP: TIMELINE --><?php include_once 'partials/timeline.php'?>
<!-- PHP: FOOTER --><?php include_once 'partials/footer.php';?>