Fóra
The great place to discuss topics with other users
Swipe like Tinder
'🔥 Swipe Feature Now Live on My Site
I have successfully implemented a fully functional Swipe (Tinder-style) feature on my social network.
👉 How it works:
-
The system randomly loads members who are not yet friends with the logged-in user.
-
Each profile is displayed in a full-screen swipe card with the user’s avatar and username.
-
Users can swipe (or click) to move to the next profile.
-
Clicking on a card redirects to the full profile page.
-
The interface is responsive and mobile-friendly.
👉 Important rules:
-
Blocked, banned, or inactive accounts are excluded.
-
Existing friends and pending requests (incoming or outgoing) are excluded.
-
Encouragement for members: before sending a friend request, they should open the profile and use the “Message” button to start chatting.
This feature is lightweight, doesn’t require touching the core, and can be fully implemented via custom pages (custom_swipe.php + custom_swipe.tpl) inside Sngine.
I dont respond to any message. I am not developper, i made that and all my functions and customizations, using Google/ChatGpt/Some Logic, so please, USE YOUR BRAIN BROTHER.
class-user.php
// SWIPE LIKE TINDER
public function get_swipe_users($limit = 20) {
global $db; $users = []; $get_users = $db->query(sprintf(" SELECT u.user_id, u.user_name, u.user_firstname, u.user_lastname, u.user_gender, u.user_picture, u.judet, ug.user_group_title FROM users u LEFT JOIN users_groups ug ON u.user_group_custom = ug.user_group_id WHERE u.user_id != %s ORDER BY RAND() LIMIT %d", secure($this->_data['user_id']), (int)$limit)); while ($user = $get_users->fetch_assoc()) { $user['user_picture'] = get_picture($user['user_picture'], $user['user_gender']); $users[] = $user; } return $users;}<?php/** * @package Sngine * @author Zamblek */// fetch bootloaderrequire('bootloader.php');// user accessuser_access();// page headerpage_header(__("Discover Swingers"));try { global $user, $db; // Get logged-in user ID $user_id = $user->_data['user_id']; // Query to get the logged-in user's group title $sql = "SELECT ug.user_group_title FROM users_groups ug JOIN users u ON u.user_group_custom = ug.user_group_id WHERE u.user_id = {$user_id} LIMIT 1"; $result = $db->query($sql); $group_title = ($result) ? $result->fetch_assoc()['user_group_title'] ?? '' : ''; // Enhance logged-in user data with group title $logged_in_user = $user->_data; $logged_in_user['user_group_title'] = $group_title; // Assign enhanced logged-in user data to Smarty $smarty->assign('_user', $logged_in_user); // Assign swipeable users (make sure get_swipe_users() returns group titles) $smarty->assign('swipe_users', $user->get_swipe_users());} catch (Exception $e) { _error(__("Error"), $e->getMessage());}// page footer - renders the templatepage_footer('your-page-name');{include file='_head.tpl'}{include file='_header.tpl'}
<style>.swipe-container { position: relative; width: 100%; height: calc(100vh - 160px); overflow: hidden; background: #000;}
.swipe-card { position: absolute; width: 100%; height: 100%; background-size: cover; background-position: center; transition: transform 0.3s ease-in-out; display: flex; flex-direction: column; justify-content: flex-end; color: #fff; padding: 20px; box-shadow: inset 0 -80px 80px rgba(0,0,0,0.6);}
.swipe-info { background: rgba(0, 0, 0, 0.6); padding: 10px; border-radius: 12px; margin-bottom: 60px;}
.swipe-info h4 { margin: 0; font-size: 22px;}
.swipe-info small { display: block; margin-top: 5px; color: #ccc;}
.profile-button { position: absolute; bottom: 15px; left: 0; width: 100%; height: 20px; padding: 15px; text-align: center; font-weight: bold; text-transform: uppercase;}
.search-wrapper-prnt { display: none !important;}
@media (max-width: 520px) { .x_side_create { display: none !important; }}</style>
<div class="row x_content_row"> <div class="col-12 position-relative"> <div id="swipeStack" class="swipe-container"> {foreach $swipe_users as $user} <div class="swipe-card" style="background-image: url('{$user.user_picture}');" data-profile="{$system['system_url']}/{$user.user_name}"> <div class="swipe-info"> <h4>{$user.user_name}</h4> <small>{$user.judet} · {$user.user_group_title}</small>
{if $user.judet == $_user.judet} <small><strong>✨ Match: Same Judet!</strong></small> {/if} {if $user.user_group_title == $_user.user_group_title} <small><strong>🔥 Same Group: {$user.user_group_title}</strong></small> {/if}
</div> <a href="{$system['system_url']}/{$user.user_name}" class="btn btn-danger profile-button">Vezi profil</a> </div> {/foreach} </div> </div></div>
{strip}{literal}<script>const stack = document.getElementById("swipeStack");let cards = Array.from(stack.querySelectorAll(".swipe-card"));let current = 0;
function showCard(index) { cards.forEach((card, i) => { card.style.zIndex = cards.length - i; card.style.transform = `translateX(${i < index ? '-100%' : i > index ? '100%' : '0'})`; });}
stack.addEventListener("click", () => { current++; if (current >= cards.length) { alert("No more users!"); return; } showCard(current);});
showCard(current);</script>{/literal}{/strip}{include file='_footer.tpl'}
Replace user.judet with your country or whatever
.htaccess
# PageRewriteRule ^your-page-name/?$ your-page-name.php [L,QSA]
For advanced user, you can use this page using swiper js , for more beautifull page:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Tinder Fullscreen Swipe</title>
<!-- Swiper CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"/>
<style> html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; background: #000; font-family: sans-serif; }
.swiper { width: 100vw; height: 100vh; overflow: hidden; }
.swiper-wrapper { width: 100%; height: 100%; }
.swiper-slide { width: 100vw !important; height: 100vh; position: relative; overflow: hidden; display: flex; align-items: flex-end; justify-content: center; }
.swiper-slide img { width: 100%; height: 100%; object-fit: cover; }
.slide-caption { position: absolute; bottom: 0; left: 0; width: 100%; padding: 20px; background: linear-gradient(to top, rgba(0,0,0,0.6), transparent); color: #fff; z-index: 10; }
.slide-caption h2 { margin: 0; font-size: 24px; }
.slide-caption p { margin: 5px 0 0; font-size: 14px; }
/* Final Slide Style */ .swiper-slide.final { background: #000; color: #fff; justify-content: center; align-items: center; text-align: center; font-size: 24px; font-weight: bold; } </style></head><body>
<!-- Swiper --> <div class="swiper mySwiper"> <div class="swiper-wrapper">
<!-- Card 1 --> <div class="swiper-slide"> <img src="https://picsum.photos/id/1005/800/1200" alt="Emily"> <div class="slide-caption"> <h2>Emily, 25</h2> <p>Adventurer & dog lover 🐶</p> </div> </div>
<!-- Card 2 --> <div class="swiper-slide"> <img src="https://picsum.photos/id/1011/800/1200" alt="Jake"> <div class="slide-caption"> <h2>Jake, 29</h2> <p>Coffee & coding ☕💻</p> </div> </div>
<!-- Card 3 --> <div class="swiper-slide"> <img src="https://picsum.photos/id/1012/800/1200" alt="Anna"> <div class="slide-caption"> <h2>Anna, 31</h2> <p>Globetrotter 🌍</p> </div> </div>
<!-- Final Slide: No More Pictures --> <div class="swiper-slide final"> No more pictures </div>
</div> </div>
<!-- Swiper JS --> <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script> <script> const swiper = new Swiper('.mySwiper', { effect: 'cards', grabCursor: true, }); </script></body></html>
I dont respond to any message. I am not developper, i made that and all my functions and customizations, using Google/ChatGpt/Some Logic, so please, USE YOUR BRAIN BROTHER.
class-user.php
// SWIPE LIKE TINDER
public function get_swipe_users($limit = 20) {
global $db; $users = []; $get_users = $db->query(sprintf(" SELECT u.user_id, u.user_name, u.user_firstname, u.user_lastname, u.user_gender, u.user_picture, u.judet, ug.user_group_title FROM users u LEFT JOIN users_groups ug ON u.user_group_custom = ug.user_group_id WHERE u.user_id != %s ORDER BY RAND() LIMIT %d", secure($this->_data['user_id']), (int)$limit)); while ($user = $get_users->fetch_assoc()) { $user['user_picture'] = get_picture($user['user_picture'], $user['user_gender']); $users[] = $user; } return $users;}<?php/** * @package Sngine * @author Zamblek */// fetch bootloaderrequire('bootloader.php');// user accessuser_access();// page headerpage_header(__("Discover Swingers"));try { global $user, $db; // Get logged-in user ID $user_id = $user->_data['user_id']; // Query to get the logged-in user's group title $sql = "SELECT ug.user_group_title FROM users_groups ug JOIN users u ON u.user_group_custom = ug.user_group_id WHERE u.user_id = {$user_id} LIMIT 1"; $result = $db->query($sql); $group_title = ($result) ? $result->fetch_assoc()['user_group_title'] ?? '' : ''; // Enhance logged-in user data with group title $logged_in_user = $user->_data; $logged_in_user['user_group_title'] = $group_title; // Assign enhanced logged-in user data to Smarty $smarty->assign('_user', $logged_in_user); // Assign swipeable users (make sure get_swipe_users() returns group titles) $smarty->assign('swipe_users', $user->get_swipe_users());} catch (Exception $e) { _error(__("Error"), $e->getMessage());}// page footer - renders the templatepage_footer('your-page-name');{include file='_head.tpl'}{include file='_header.tpl'}
<style>.swipe-container { position: relative; width: 100%; height: calc(100vh - 160px); overflow: hidden; background: #000;}
.swipe-card { position: absolute; width: 100%; height: 100%; background-size: cover; background-position: center; transition: transform 0.3s ease-in-out; display: flex; flex-direction: column; justify-content: flex-end; color: #fff; padding: 20px; box-shadow: inset 0 -80px 80px rgba(0,0,0,0.6);}
.swipe-info { background: rgba(0, 0, 0, 0.6); padding: 10px; border-radius: 12px; margin-bottom: 60px;}
.swipe-info h4 { margin: 0; font-size: 22px;}
.swipe-info small { display: block; margin-top: 5px; color: #ccc;}
.profile-button { position: absolute; bottom: 15px; left: 0; width: 100%; height: 20px; padding: 15px; text-align: center; font-weight: bold; text-transform: uppercase;}
.search-wrapper-prnt { display: none !important;}
@media (max-width: 520px) { .x_side_create { display: none !important; }}</style>
<div class="row x_content_row"> <div class="col-12 position-relative"> <div id="swipeStack" class="swipe-container"> {foreach $swipe_users as $user} <div class="swipe-card" style="background-image: url('{$user.user_picture}');" data-profile="{$system['system_url']}/{$user.user_name}"> <div class="swipe-info"> <h4>{$user.user_name}</h4> <small>{$user.judet} · {$user.user_group_title}</small>
{if $user.judet == $_user.judet} <small><strong>✨ Match: Same Judet!</strong></small> {/if} {if $user.user_group_title == $_user.user_group_title} <small><strong>🔥 Same Group: {$user.user_group_title}</strong></small> {/if}
</div> <a href="{$system['system_url']}/{$user.user_name}" class="btn btn-danger profile-button">Vezi profil</a> </div> {/foreach} </div> </div></div>
{strip}{literal}<script>const stack = document.getElementById("swipeStack");let cards = Array.from(stack.querySelectorAll(".swipe-card"));let current = 0;
function showCard(index) { cards.forEach((card, i) => { card.style.zIndex = cards.length - i; card.style.transform = `translateX(${i < index ? '-100%' : i > index ? '100%' : '0'})`; });}
stack.addEventListener("click", () => { current++; if (current >= cards.length) { alert("No more users!"); return; } showCard(current);});
showCard(current);</script>{/literal}{/strip}{include file='_footer.tpl'}
Replace user.judet with your country or whatever
.htaccess
# PageRewriteRule ^your-page-name/?$ your-page-name.php [L,QSA]
For advanced user, you can use this page using swiper js , for more beautifull page:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Tinder Fullscreen Swipe</title>
<!-- Swiper CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"/>
<style> html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; background: #000; font-family: sans-serif; }
.swiper { width: 100vw; height: 100vh; overflow: hidden; }
.swiper-wrapper { width: 100%; height: 100%; }
.swiper-slide { width: 100vw !important; height: 100vh; position: relative; overflow: hidden; display: flex; align-items: flex-end; justify-content: center; }
.swiper-slide img { width: 100%; height: 100%; object-fit: cover; }
.slide-caption { position: absolute; bottom: 0; left: 0; width: 100%; padding: 20px; background: linear-gradient(to top, rgba(0,0,0,0.6), transparent); color: #fff; z-index: 10; }
.slide-caption h2 { margin: 0; font-size: 24px; }
.slide-caption p { margin: 5px 0 0; font-size: 14px; }
/* Final Slide Style */ .swiper-slide.final { background: #000; color: #fff; justify-content: center; align-items: center; text-align: center; font-size: 24px; font-weight: bold; } </style></head><body>
<!-- Swiper --> <div class="swiper mySwiper"> <div class="swiper-wrapper">
<!-- Card 1 --> <div class="swiper-slide"> <img src="https://picsum.photos/id/1005/800/1200" alt="Emily"> <div class="slide-caption"> <h2>Emily, 25</h2> <p>Adventurer & dog lover 🐶</p> </div> </div>
<!-- Card 2 --> <div class="swiper-slide"> <img src="https://picsum.photos/id/1011/800/1200" alt="Jake"> <div class="slide-caption"> <h2>Jake, 29</h2> <p>Coffee & coding ☕💻</p> </div> </div>
<!-- Card 3 --> <div class="swiper-slide"> <img src="https://picsum.photos/id/1012/800/1200" alt="Anna"> <div class="slide-caption"> <h2>Anna, 31</h2> <p>Globetrotter 🌍</p> </div> </div>
<!-- Final Slide: No More Pictures --> <div class="swiper-slide final"> No more pictures </div>
</div> </div>
<!-- Swiper JS --> <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script> <script> const swiper = new Swiper('.mySwiper', { effect: 'cards', grabCursor: true, }); </script></body></html>