all atb changes

This commit is contained in:
Joey Kimsey
2025-02-05 23:57:17 -05:00
parent 2ac64e5c49
commit ffb82b1192
328 changed files with 12384 additions and 2477 deletions

View File

@ -1,7 +1,7 @@
{LOOP}
<article class="blog-post context-main-bg p-2">
<h2 class="blog-post-title mb-1">{title}</h2>
<p class="blog-post-meta">{DTC date}{created}{/DTC} by <a href="{ROOT_URL}home/profile/{authorName}" class="text-decoration-none">{authorName}</a></p>
<p class="blog-post-meta">{DTC date}{created}{/DTC} by <a href="{ROOT_URL}home/profile/{authorName}" class="text-decoration-none atb-green">{authorName}</a></p>
<div class="well">
{contentSummary}
</div>

View File

@ -3,7 +3,7 @@
<div class="blog-post mb-5 pb-5">
<h2 class="blog-post-title">{title}</h2>
<hr>
<p class="blog-post-meta">{DTC date}{created}{/DTC} by <a href="{ROOT_URL}home/profile/{authorName}" class="text-decoration-none">{authorName}</a></p>
<p class="blog-post-meta">{DTC date}{created}{/DTC} by <a href="{ROOT_URL}home/profile/{authorName}" class="text-decoration-none atb-green">{authorName}</a></p>
{content}
{ADMIN}
<hr>

View File

@ -6,7 +6,7 @@
<div class="card-body context-second-bg">
<ol class="list-unstyled">
{LOOP}
<li>({count}) <a href="{ROOT_URL}blog/month/{month}/{year}" class="text-decoration-none">{monthText} {year}</a></li>
<li>({count}) <a href="{ROOT_URL}blog/month/{month}/{year}" class="text-decoration-none atb-green">{monthText} {year}</a></li>
{/LOOP}
{ALT}
<li>None To Show</li>

View File

@ -0,0 +1,68 @@
<?php
/**
* app/plugins/bookmarks/controllers/api/bookmark_folders.php
*
* This is the api bookmark folders controller.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers\Api;
use TheTempusProject\Models\User;
use TheTempusProject\Classes\ApiController;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Canary\Bin\Canary as Debug;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Models\Folders;
class BookmarkFolders extends ApiController {
protected static $folders;
public function __construct() {
header('Access-Control-Allow-Origin: *');
parent::__construct();
self::$folders = new Folders;
}
public function create() {
$user = self::$authToken->createdBy;
$payload = @file_get_contents('php://input');
$payload = json_decode( $payload, true );
$result = self::$folders->create(
$payload['name'],
$payload['folder'] ?? 0,
$payload['notes'] ?? '',
$payload['color'] ?? 'default',
$payload['privacy'] ?? 'private',
$user
);
if ( ! $result ) {
$responseType = 'error';
$response = 'There was an error creating your folder.';
} else {
$responseType = 'id';
$response = $result;
}
Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
}
public function list( $id = '' ) {
$user = self::$authToken->createdBy;
$folders = self::$folders->bySpecificUser( $user );
if ( ! $folders ) {
$responseType = 'error';
$response = 'There was an error creating your folder.';
} else {
$responseType = 'folders';
$response = $folders;
}
Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* app/plugins/bookmarks/controllers/api/bookmarks.php
*
* This is the api bookmarks controller.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers\Api;
use TheTempusProject\Models\User;
use TheTempusProject\Classes\ApiController;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Canary\Bin\Canary as Debug;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Models\Bookmarks as Bookmark;
class Bookmarks extends ApiController {
protected static $bookmarks;
public function __construct() {
parent::__construct();
self::$bookmarks = new Bookmark;
}
public function create() {
header('Access-Control-Allow-Origin: *');
$user = self::$authToken->createdBy;
$payload = @file_get_contents('php://input');
$payload = json_decode( $payload, true );
$result = self::$bookmarks->create(
$payload['name'],
$payload['url'],
$payload['folder'] ?? 0,
$payload['notes'] ?? '',
$payload['color'] ?? 'default',
$payload['privacy'] ?? 'private',
'external',
$user
);
if ( ! $result ) {
$responseType = 'error';
$response = 'There was an error creating your folder.';
} else {
$responseType = 'data';
$response = $result;
}
Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
}
}

View File

@ -0,0 +1,992 @@
<?php
/**
* app/plugins/bookmarks/controllers/bookmarks.php
*
* This is the bookmarks controller.
*
* @package TP Bookmarks
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers;
use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Classes\Forms;
use TheTempusProject\Models\Bookmarks as Bookmark;
use TheTempusProject\Models\Folders;
use TheTempusProject\Models\BookmarkDashboards as Dashboards;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Houdini\Classes\Forms as HoudiniForms;
use TheTempusProject\Houdini\Classes\Navigation;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Models\User;
use TheTempusProject\Classes\Preferences;
use TheTempusProject\Canary\Bin\Canary as Debug;
class Bookmarks extends Controller {
protected static $bookmarks;
protected static $folders;
protected static $dashboards;
public function __construct() {
parent::__construct();
if ( ! App::$isLoggedIn ) {
Session::flash( 'notice', 'You must be logged in to create or manage bookmarks.' );
return Redirect::home();
}
self::$bookmarks = new Bookmark;
self::$folders = new Folders;
self::$dashboards = new Dashboards;
self::$title = 'Bookmarks - {SITENAME}';
self::$pageDescription = 'Add and save url bookmarks here.';
$folderTabs = Views::simpleView( 'bookmarks.nav.folderTabs' );
if ( stripos( Input::get('url'), 'bookmarks/bookmarks' ) !== false ) {
$tabsView = Navigation::activePageSelect( $folderTabs, '/bookmarks/folders/', false, true );
$userFolderTabs = Views::simpleView('bookmarks.nav.userFolderTabs', self::$folders->simpleObjectByUser(true) );
$userFolderTabsView = Navigation::activePageSelect( $userFolderTabs, Input::get( 'url' ), false, true );
} else {
$tabsView = Navigation::activePageSelect( $folderTabs, Input::get( 'url' ), false, true );
$userFolderTabsView = '';
}
Components::set( 'userFolderTabs', $userFolderTabsView );
Components::set( 'SITE_URL', Routes::getAddress() );
Views::raw( $tabsView );
Components::append( 'TEMPLATE_JS_INCLUDES', Template::parse('<script language="JavaScript" crossorigin="anonymous" type="text/javascript" src="{ROOT_URL}app/plugins/bookmarks/js/bookmarks.js"></script>' ) );
$viewOptions = Views::simpleView( 'bookmarks.nav.viewOptions' );
Components::set( 'VIEW_OPTIONS', $viewOptions );
$dashOptions = Views::simpleView( 'bookmarks.dashboards.dashOptions' );
Components::set( 'DASH_OPTIONS', $dashOptions );
$this->setPrefToggles();
}
public function index() {
self::$title = 'Manage Bookmarks - {SITENAME}';
if ( Input::exists('submit') ) {
$prefs = new Preferences;
$user = new User;
$fields = $prefs->convertFormToArray( true );
$out = $user->updatePrefs( $fields, App::$activeUser->ID );
$this->setPrefToggles();
}
$folders = self::$folders->byUser();
$panelArray = [];
if ( !empty( $folders ) ) {
foreach ( $folders as $folder ) {
$panel = new \stdClass();
$folderObject = new \stdClass();
$folderObject->bookmarks = self::$bookmarks->byFolder( $folder->ID );
$folderObject->ID = $folder->ID;
$folderObject->title = $folder->title;
$folderObject->color = $folder->color;
$folderObject->uuid = $folder->uuid;
$folderObject->bookmarkListRows = Views::simpleView( 'bookmarks.components.bookmarkListRows', $folderObject->bookmarks );
$panelArray[] = $folderObject;
}
}
if ( ! empty( $folders ) ) {
Components::set( 'folderPanels', Views::simpleView( 'bookmarks.components.bookmarkListPanel', $panelArray ) );
return Views::view( 'bookmarks.dash' );
}
return Views::view( 'bookmarks.indexExplainer' );
}
/**
* Bookmarks
*/
public function bookmark( $id = 0 ) {
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Session::flash( 'error', 'Bookmark not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
return Redirect::to( 'bookmarks/index' );
}
Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/bookmark/' . $id );
return Views::view( 'bookmarks.bookmarks.view', $bookmark );
}
public function unsorted() {
self::$title = 'Unsorted Bookmarks - {SITENAME}';
$bookmarks = self::$bookmarks->noFolder();
Views::view( 'bookmarks.bookmarks.unsorted', $bookmarks );
}
public function bookmarks( $id = null ) {
$folder = self::$folders->findById( $id );
if ( $folder == false ) {
Session::flash( 'error', 'Folder not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $folder->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to view this folder.' );
return Redirect::to( 'bookmarks/index' );
}
Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/bookmarks/' . $id );
$panelArray = [];
$panel = new \stdClass();
$folderObject = new \stdClass();
$folderObject->bookmarks = self::$bookmarks->byFolder( $folder->ID );
$folderObject->ID = $folder->ID;
$folderObject->title = $folder->title;
$folderObject->color = $folder->color;
$folderObject->bookmarkListRows = Views::simpleView( 'bookmarks.components.bookmarkListRows', $folderObject->bookmarks );
$panel->panel = Views::simpleView( 'bookmarks.components.bookmarkListPanel', [$folderObject] );
$panelArray[] = $panel;
return Views::view( 'bookmarks.bookmarks.listPage', $panelArray );
}
public function createBookmark( $id = null ) {
self::$title = 'Add Bookmark - {SITENAME}';
$folderID = Input::get('folder_id') ? Input::get('folder_id') : $id;
$folderID = Input::post('folder_id') ? Input::post('folder_id') : $id;
$this->setFolderSelect( $folderID );
if ( ! Input::exists() ) {
return Views::view( 'bookmarks.bookmarks.create' );
}
if ( ! Forms::check( 'createBookmark' ) ) {
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
return Views::view( 'bookmarks.bookmarks.create' );
}
$result = self::$bookmarks->create(
Input::post('title'),
Input::post('url'),
$folderID,
Input::post('description'),
Input::post('color'),
Input::post('privacy'),
);
if ( ! $result ) {
Issues::add( 'error', [ 'There was an error creating your bookmark.' => Check::userErrors() ] );
return Views::view( 'bookmarks.bookmarks.create' );
}
// self::$bookmarks->refreshInfo( $result );
Session::flash( 'success', 'Your Bookmark has been created.' );
if ( ! empty( $folderID ) ) {
Redirect::to( 'bookmarks/bookmarks/'. $folderID );
} else {
Redirect::to( 'bookmarks/index' );
}
}
public function editBookmark( $id = null ) {
self::$title = 'Edit Bookmark - {SITENAME}';
$folderID = Input::exists('folder_id') ? Input::post('folder_id') : '';
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Issues::add( 'error', 'Bookmark not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to modify this bookmark.' );
return Redirect::to( 'bookmarks/index' );
}
if ( empty( $folderID ) ) {
$folderID = $bookmark->folderID;
}
$this->setFolderSelect( $folderID );
Components::set( 'color', $bookmark->color );
if ( ! Input::exists( 'submit' ) ) {
return Views::view( 'bookmarks.bookmarks.edit', $bookmark );
}
if ( ! Forms::check( 'editBookmark' ) ) {
Issues::add( 'error', [ 'There was an error updating your bookmark.' => Check::userErrors() ] );
return Views::view( 'bookmarks.bookmarks.edit', $bookmark );
}
$result = self::$bookmarks->update(
$id,
Input::post('title'),
Input::post('url'),
$folderID,
Input::post('description'),
Input::post('color'),
Input::post('privacy'),
);
if ( ! $result ) {
Issues::add( 'error', [ 'There was an error updating your bookmark.' => Check::userErrors() ] );
return Views::view( 'bookmarks.bookmarks.edit', $bookmark );
}
Session::flash( 'success', 'Your Bookmark has been updated.' );
Redirect::to( 'bookmarks/folders/'. $bookmark->folderID );
}
public function deleteBookmark( $id = null ) {
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Issues::add( 'error', 'Bookmark not found.' );
return $this->index();
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to modify this bookmark.' );
return $this->index();
}
$result = self::$bookmarks->delete( $id );
if ( !$result ) {
Session::flash( 'error', 'There was an error deleting the bookmark(s)' );
} else {
Session::flash( 'success', 'Bookmark deleted' );
}
Redirect::to( 'bookmarks/folders/'. $bookmark->folderID );
}
/**
* Folders
*/
public function folders( $id = null) {
$folder = self::$folders->findById( $id );
if ( $folder == false ) {
$folders = self::$folders->byUser();
Components::set( 'foldersList', Views::simpleView( 'bookmarks.folders.list', $folders ) );
return Views::view( 'bookmarks.folders.listPage' );
}
if ( $folder->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to view this folder.' );
return Redirect::to( 'bookmarks/index' );
}
Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/folders/' . $id );
return Views::view( 'bookmarks.folders.view', $folder );
}
public function createFolder( $id = 0 ) {
self::$title = 'Create Folder - {SITENAME}';
$folderID = Input::exists('folder_id') ? Input::post('folder_id') : $id;
$folders = self::$folders->simpleByUser();
if ( ! empty( $folders ) ) {
$this->setFolderSelect( $folderID );
} else {
$folderSelect = '';
Components::set( 'folderSelect', $folderSelect );
}
if ( ! Input::exists() ) {
return Views::view( 'bookmarks.folders.create' );
}
if ( ! Forms::check( 'createFolder' ) ) {
Issues::add( 'error', [ 'There was an error creating your folder.' => Check::userErrors() ] );
return Views::view( 'bookmarks.folders.create' );
}
$folder = self::$folders->create( Input::post('title'), $folderID, Input::post('description'), Input::post('color'), Input::post('privacy') );
if ( ! $folder ) {
return Views::view( 'bookmarks.folders.create' );
}
Session::flash( 'success', 'Your Folder has been created.' );
Redirect::to( 'bookmarks/folders' );
}
public function editFolder( $id = null ) {
self::$title = 'Edit Folder - {SITENAME}';
$folder = self::$folders->findById( $id );
if ( $folder == false ) {
Issues::add( 'error', 'Folder not found.' );
return $this->index();
}
if ( $folder->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to modify this folder.' );
return $this->index();
}
$folderID = ( false === Input::exists('folder_id') ) ? $folder->ID : Input::post('folder_id');
$this->setFolderSelect( $folderID );
Components::set( 'color', $folder->color );
if ( ! Input::exists( 'submit' ) ) {
return Views::view( 'bookmarks.folders.edit', $folder );
}
if ( !Forms::check( 'editFolder' ) ) {
Issues::add( 'error', [ 'There was an error editing your folder.' => Check::userErrors() ] );
return Views::view( 'bookmarks.folders.edit', $folder );
}
$result = self::$folders->update( $id, Input::post('title'), $folderID, Input::post('description'), Input::post('color'), Input::post('privacy') );
if ( !$result ) {
Issues::add( 'error', [ 'There was an error updating your folder.' => Check::userErrors() ] );
return Views::view( 'bookmarks.folders.edit', $folder );
}
Session::flash( 'success', 'Your Folder has been updated.' );
Redirect::to( 'bookmarks/folders/'. $folder->ID );
}
public function deleteFolder( $id = null ) {
$folder = self::$folders->findById( $id );
if ( $folder == false ) {
Issues::add( 'error', 'Folder not found.' );
return $this->index();
}
if ( $folder->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to modify this folder.' );
return $this->index();
}
$results = self::$bookmarks->deleteByFolder( $id );
$result = self::$folders->delete( $id );
if ( !$result ) {
Session::flash( 'error', 'There was an error deleting the folder(s)' );
} else {
Session::flash( 'success', 'Folder deleted' );
}
Redirect::to( 'bookmarks/folders' );
}
/**
* Dashboards
*/
public function addDash() {
self::$title = 'Add Dashboard - {SITENAME}';
if ( !App::$isMember ) {
Issues::add( 'notice', 'You must have an active membership to add dashboards.' );
return $this->index();
}
$folders = self::$folders->byUser() ?? [];
if ( !empty( $folders ) ) {
foreach ( $folders as &$folder ) {
$folder->selected = '';
}
}
$linkSelect = Views::simpleView( 'bookmarks.components.linkSelect', $folders );
Components::set( 'LINK_SELECT', $linkSelect );
if ( ! Input::exists( 'submit' ) ) {
return Views::view( 'bookmarks.dashboards.create' );
}
if ( !Forms::check( 'createDashboard' ) ) {
Issues::add( 'error', [ 'There was an error creating your dashboard.' => Check::userErrors() ] );
return Views::view( 'bookmarks.dashboards.create' );
}
if ( is_array( Input::post('link_filter') ) && ! empty( Input::post('link_filter') ) ) {
$filters = implode( ',', Input::post('link_filter') );
} else {
$filters = '';
}
if ( is_array( Input::post('link_order') ) && ! empty( Input::post('link_order') ) ) {
$folders = implode( ',', Input::post('link_order') );
} else {
$folders = '';
}
$result = self::$dashboards->create( Input::post('title'), $filters, $folders, Input::post('description') );
if ( !$result ) {
Issues::add( 'error', [ 'There was an error creating your dashboard.' => Check::userErrors() ] );
return Views::view( 'bookmarks.dashboards.create' );
}
Issues::add( 'success', 'Your dashboard has been created.' );
return $this->dashboards();
}
public function editDash( $id = null ) {
self::$title = 'Edit Dashboard - {SITENAME}';
if ( !App::$isMember ) {
Issues::add( 'notice', 'You must have an active membership to edit dashboards.' );
return $this->index();
}
$dash = self::$dashboards->findById( $id );
if ( $dash == false ) {
Issues::add( 'error', 'Unknown Dashboard' );
return $this->dashboards();
}
if ( $dash->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to view this dashboard.' );
return $this->dashboards();
}
$this->setDashToggles( explode( ',', $dash->saved_prefs ) );
$folders = self::$folders->byUser() ?? [];
$selectedFolders = explode( ',', $dash->link_order );
if ( !empty( $folders ) ) {
foreach ( $folders as &$folder ) {
if ( in_array( $folder->ID, $selectedFolders ) ) {
$folder->selected = ' checked';
} else {
$folder->selected = '';
}
}
}
$linkSelect = Views::simpleView( 'bookmarks.components.linkSelect', $folders );
Components::set( 'LINK_SELECT', $linkSelect );
if ( ! Input::exists( 'submit' ) ) {
return Views::view( 'bookmarks.dashboards.edit', $dash );
}
if ( ! Forms::check( 'editDashboard' ) ) {
Issues::add( 'error', [ 'There was an error editing your dashboard.' => Check::userErrors() ] );
return Views::view( 'bookmarks.dashboards.edit', $dash );
}
if ( is_array( Input::post('link_filter') ) && ! empty( Input::post('link_filter') ) ) {
$filters = implode( ',', Input::post('link_filter') );
} else {
$filters = '';
}
if ( is_array( Input::post('link_order') ) && ! empty( Input::post('link_order') ) ) {
$folders = implode( ',', Input::post('link_order') );
} else {
$folders = '';
}
$result = self::$dashboards->update( $id, Input::post('title'), $filters, $folders, Input::post('description') );
if ( !$result ) {
Issues::add( 'error', [ 'There was an error updating your dashboard.' => Check::userErrors() ] );
return Views::view( 'bookmarks.dashboards.edit', $dash );
}
Issues::add( 'success', 'Your dashboard has been updated.' );
return $this->dashboards();
}
public function deleteDash( $id = null ) {
if ( !App::$isMember ) {
Issues::add( 'notice', 'You must have an active membership to delete dashboards.' );
return $this->index();
}
$dash = self::$dashboards->findById( $id );
if ( $dash == false ) {
Issues::add( 'error', 'Unknown Dashboard' );
return $this->dashboards();
}
if ( $dash->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to delete this dash.' );
return $this->dashboards();
}
$result = self::$dashboards->delete( $id );
if ( !$result ) {
Issues::add( 'error', 'There was an error deleting the dashboard(s)' );
} else {
Issues::add( 'success', 'Dashboard deleted' );
}
return $this->dashboards();
}
public function dashboard( $uuid = null ) {
self::$title = 'Bookmark Dashboard - {SITENAME}';
if ( !App::$isMember ) {
Issues::add( 'notice', 'You must have an active membership to view dashboards.' );
return $this->index();
}
$dash = self::$dashboards->findByUuid( $uuid );
if ( $dash == false ) {
return $this->dashboards();
}
if ( $dash->createdBy != App::$activeUser->ID ) {
Issues::add( 'error', 'You do not have permission to view this dash.' );
return $this->dashboards();
}
if ( Input::exists( 'submit' ) ) {
if ( Forms::check( 'updateDashboard' ) ) {
$filters = '';
$folders = '';
if ( is_array( Input::post('link_filter') ) && ! empty( Input::post('link_filter') ) ) {
$filters = implode( ',', Input::post('link_filter') );
}
if ( ! empty( Input::post('link_order') ) ) {
$folders = Input::post('link_order');
}
$result = self::$dashboards->updateDash( $dash->ID, $filters, $folders );
if ( !$result ) {
Issues::add( 'error', [ 'There was an error saving your dashboard.' => Check::userErrors() ] );
} else {
Issues::add( 'success', 'Your dashboard has been saved.' );
}
} else {
Issues::add( 'error', [ 'There was an error saving your dashboard.' => Check::userErrors() ] );
}
unset( $_POST );
}
$dash = self::$dashboards->findByUuid( $uuid );
$foldersArray = [];
if ( ! empty( $dash->link_order ) ) {
$folders = explode( ',', $dash->link_order );
foreach ( $folders as $key => $id ) {
$folder = self::$folders->findById( $id );
if ( empty( $folder ) ) {
continue;
}
$bookmarks = self::$bookmarks->byFolder( $folder->ID );
if ( empty( $bookmarks ) ) {
continue;
}
$folderObject = new \stdClass();
$folderObject->ID = $folder->ID;
$folderObject->title = $folder->title;
$folderObject->color = $folder->color;
$folderObject->uuid = $folder->uuid;
$folderObject->bookmarkRows = Views::simpleView( 'bookmarks.dashboards.bookmarkRows', $bookmarks );
$foldersArray[] = $folderObject;
}
}
Components::set( 'folderPanels', Views::simpleView( 'bookmarks.dashboards.folderPanels', $foldersArray ) );
if ( ! empty( $dash->saved_prefs ) ) {
$this->setDashToggles( explode( ',', $dash->saved_prefs ) );
} else {
$this->setDashToggles( [] );
}
return Views::view( 'bookmarks.dashboards.view', $dash );
}
public function dashboards() {
self::$title = 'Bookmark Dashboards - {SITENAME}';
if ( !App::$isMember ) {
Issues::add( 'notice', 'You will need an active subscription to start creating dashboards. You can check our <a href="/member/join" class="text-decoration-none">Pricing</a> page for more details.' );
return Views::view( 'bookmarks.dashboardExplainer' );
}
$dashboards = self::$dashboards->byUser();
return Views::view( 'bookmarks.dashboards.list', $dashboards );
}
/**
* Functionality
*/
public function publish( $id = null ) {
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Session::flash( 'error', 'Bookmark not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
return Redirect::to( 'bookmarks/index' );
}
self::$bookmarks->publish( $id );
Session::flash( 'success', 'Bookmark mad Public.' );
return Redirect::to( 'bookmarks/share' );
}
public function retract( $id = null ) {
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Session::flash( 'error', 'Bookmark not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
return Redirect::to( 'bookmarks/index' );
}
self::$bookmarks->retract( $id );
Session::flash( 'success', 'Bookmark made Private.' );
return Redirect::to( 'bookmarks/share' );
}
public function hideBookmark( $id = null ) {
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Session::flash( 'error', 'Bookmark not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
return Redirect::to( 'bookmarks/index' );
}
self::$bookmarks->hide( $id );
Session::flash( 'success', 'Bookmark hidden.' );
return Redirect::to( 'bookmarks/index' );
}
public function archiveBookmark( $id = null ) {
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Session::flash( 'error', 'Bookmark not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
return Redirect::to( 'bookmarks/index' );
}
self::$bookmarks->archive( $id );
Session::flash( 'success', 'Bookmark archived.' );
return Redirect::to( 'bookmarks/index' );
}
public function showBookmark( $id = null ) {
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Session::flash( 'error', 'Bookmark not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
return Redirect::to( 'bookmarks/index' );
}
self::$bookmarks->show( $id );
Session::flash( 'success', 'Bookmark shown.' );
return Redirect::to( 'bookmarks/index' );
}
public function unarchiveBookmark( $id = null ) {
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Session::flash( 'error', 'Bookmark not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
return Redirect::to( 'bookmarks/index' );
}
self::$bookmarks->unarchive( $id );
Session::flash( 'success', 'Bookmark un-archived.' );
return Redirect::to( 'bookmarks/index' );
}
public function refreshBookmark( $id = null ) {
$bookmark = self::$bookmarks->findById( $id );
if ( $bookmark == false ) {
Session::flash( 'error', 'Bookmark not found.' );
return Redirect::to( 'bookmarks/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
Session::flash( 'error', 'You do not have permission to modify this bookmark.' );
return Redirect::to( 'bookmarks/index' );
}
$info = self::$bookmarks->refreshInfo( $id );
if ( false == $info ) {
Session::flash( 'error', 'Issue refreshing your bookmark.' );
return Redirect::to( 'bookmarks/bookmark/' . $bookmark->ID );
}
Session::flash( 'success', 'Bookmark data refreshed.' );
return Redirect::to( 'bookmarks/bookmark/' . $bookmark->ID );
}
public function import() {
self::$title = 'Bookmark Import - {SITENAME}';
if ( !App::$isMember ) {
Issues::add( 'notice', 'You will need an active subscription to start importing bookmarks. You can check our <a href="/member/join" class="text-decoration-none">Pricing</a> page for more details.' );
return Views::view( 'bookmarks.importExplainer' );
}
if ( ! Input::exists('submit') ) {
return Views::view( 'bookmarks.import' );
}
if ( ! Forms::check( 'importBookmarks' ) ) {
Issues::add( 'error', [ 'There was an error importing your bookmarks.' => Check::userErrors() ] );
return Views::view( 'bookmarks.import' );
}
if ( isset( $_FILES['bookmark_file'] ) ) {
$file = $_FILES['bookmark_file'];
if ($file['size'] > 1024 * 1024) { // 1024 KB = 1 MB
Issues::add( 'error', 'There is a 1 meg limit on bookmark imports at this time.' );
return Views::view( 'bookmarks.import' );
}
$fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if ($fileExtension !== 'html') {
Issues::add( 'error', 'Invalid file type. Only .html files are allowed.' );
return Views::view( 'bookmarks.import' );
}
$fileContent = file_get_contents($file['tmp_name']);
} else {
Issues::add( 'error', 'No Import detected' );
return Views::view( 'bookmarks.import' );
}
$out = $this->parseBookmarks($fileContent);
$date = date('F j, Y');
$description = 'Imported on ' . $date . ' from file: ' . $file['name'];
$importFolder = self::$folders->create( 'New Import', 0, $description );
foreach ($out as $folder => $bookmarks) {
$currentFolder = self::$folders->create( $folder, $importFolder, $description );
foreach ($bookmarks as $index => $bookmark) {
self::$bookmarks->create( $bookmark['name'], $bookmark['url'], $currentFolder);
}
}
Session::flash( 'success', 'Your Bookmark has been created.' );
Redirect::to( 'bookmarks/bookmarks/'. $importFolder );
}
public function export() {
self::$title = 'Bookmark Export - {SITENAME}';
if ( !App::$isMember ) {
Issues::add( 'notice', 'You will need an active subscription to start exporting bookmarks. You can check our <a href="/member/join" class="text-decoration-none">Pricing</a> page for more details.' );
return Views::view( 'bookmarks.exportExplainer' );
}
$folders = self::$folders->byUser();
if ( ! Input::exists('submit') ) {
return Views::view( 'bookmarks.export', $folders );
}
if ( ! Forms::check( 'exportBookmarks' ) ) {
Issues::add( 'error', [ 'There was an error exporting your bookmarks.' => Check::userErrors() ] );
return Views::view( 'bookmarks.export', $folders );
}
$htmlDoc = '';
$htmlDoc .= '<!DOCTYPE NETSCAPE-Bookmark-file-1>' . PHP_EOL;
$htmlDoc .= '<!-- This is an automatically generated file.' . PHP_EOL;
$htmlDoc .= ' It will be read and overwritten.' . PHP_EOL;
$htmlDoc .= ' DO NOT EDIT! -->' . PHP_EOL;
$htmlDoc .= '<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">' . PHP_EOL;
$htmlDoc .= '<TITLE>Bookmarks</TITLE>' . PHP_EOL;
$htmlDoc .= '<H1>Bookmarks</H1>' . PHP_EOL;
$htmlDoc .= '<DL><p>' . PHP_EOL;
foreach ( Input::post('BF_') as $key => $id ) {
if ( $id == 'unsorted' ) {
continue;
}
$folder = self::$folders->findById( $id );
if ( $folder == false ) {
Session::flash( 'error', 'Folder not found.' );
return Redirect::to( 'bookmarks/index' );
}
$hiddenExcluded = ! ( Input::post('hiddenIncluded') ?? false );
$archivedExcluded = ! ( Input::post('archivedIncluded') ?? false );
$links = self::$bookmarks->byFolder( $folder->ID, $hiddenExcluded, $archivedExcluded );
$htmlDoc .= $this->exportFolder( $folder->title, $folder->createdAt, $folder->createdAt, $links );
}
$htmlDoc .= '</DL><p>' . PHP_EOL;
$folder = UPLOAD_DIRECTORY . App::$activeUser->username;
if ( !file_exists( $folder ) ) {
mkdir( $folder, 0777, true );
}
$file = $folder . DIRECTORY_SEPARATOR . 'export.html';
$result = file_put_contents( $file, $htmlDoc );
if ($result !== false) {
$filename = basename($file);
$downloadUrl = '/uploads/' . App::$activeUser->username . '/export.html';
Session::flash( 'success', 'Your Export is available for download <a target="_blank" href="' . $downloadUrl . '">here</a>.' );
Redirect::to( 'bookmarks/export' );
} else {
Session::flash( 'error', 'There was an issue exporting your bookmarks, please try again.' );
return Redirect::to( 'bookmarks/export' );
}
}
public function share() {
$panelArray = [];
$folders = self::$folders->byUser();
if ( empty( $folders ) ) {
return Views::view( 'bookmarks.shareExplainer' );
}
foreach ( $folders as $key => $folder ) {
$panel = new \stdClass();
$folderObject = new \stdClass();
if ( $folder->privacy == 'private' ) {
$links = self::$bookmarks->publicByFolder( $folder->ID );
} else {
$links = self::$bookmarks->byFolder( $folder->ID );
}
$folderObject->bookmarks = $links;
$folderObject->ID = $folder->ID;
$folderObject->uuid = $folder->uuid;
$folderObject->title = $folder->title;
$folderObject->color = $folder->color;
$folderObject->privacyBadge = $folder->privacyBadge;
$folderObject->bookmarkListRows = Views::simpleView( 'bookmarks.components.shareListRows', $folderObject->bookmarks );
$panel->panel = Views::simpleView( 'bookmarks.components.shareListPanel', [$folderObject] );
$panelArray[] = $panel;
}
return Views::view( 'bookmarks.share', $panelArray );
}
/**
* Private
*/
private function exportFolder( $title, $editedAt, $createdAt, $links ) {
$htmlDoc = '<DT><H3 ADD_DATE="'.$createdAt.'" LAST_MODIFIED="'.$editedAt.'">'.$title.'</H3>' . PHP_EOL;
$htmlDoc .= '<DL><p>' . PHP_EOL;
if ( ! empty( $links ) ) {
foreach ( $links as $key => $link ) {
$htmlDoc .= $this->exportLink( $link->url, $link->icon, $link->createdAt, $link->title );
}
}
$htmlDoc .= '</DL><p>' . PHP_EOL;
return $htmlDoc;
}
private function exportLink( $url, $icon, $createdAt, $title ) {
$htmlDoc = '<DT><A HREF="'.$url.'" ADD_DATE="'.$createdAt.'" ICON="'.$icon.'">'.$title.'</A>' . PHP_EOL;
return $htmlDoc;
}
private function parseBookmarks($htmlContent) {
$started = false;
$out = [];
$currentFolder = [];
$folderName = ['unknown'];
$lines = explode("\n", $htmlContent);
foreach ($lines as $line) {
if ( $started == false ) {
if (preg_match("/<h1>(.*?)<\/h1>/i", $line, $matches)) {
$started = true;
}
continue;
}
if (preg_match('/<DL><p>/i', $line, $matches)) {
continue;
}
if (preg_match('/<H3(.*)>(.*?)<\/h3>/i', $line, $matches)) {
$newFolder = $matches[2];
$out[$newFolder] = [];
array_unshift($folderName, $newFolder );
continue;
}
if (preg_match('/<\/DL><p>/i', $line, $matches)) {
array_shift($folderName);
continue;
}
if (preg_match('/<A HREF="(.*?)"(.*)>(.*?)<\/A>/i', $line, $matches)) {
$href = $matches[1];
$guts = $matches[2];
$text = $matches[3];
$added = '';
$icon = '';
if (preg_match('/ADD_DATE="(.*?)"/i', $guts, $addMatches)) {
$added = $addMatches[1];
}
if (preg_match('/ICON="(.*?)"/i', $guts, $iconMatches)) {
$icon = $iconMatches[1];
}
$currentFolder = $folderName[0];
$out[$currentFolder][] = [
'name' => $text,
'url' => $href,
'addDate' => $added,
'icon' => $icon,
'folderName' => $folderName[0],
];
continue;
}
}
return $out;
}
private function setFolderSelect( $folderID ) {
$options = self::$folders->simpleByUser();
$out = '';
$out .= '<div class="mb-3 row">';
$out .= '<label for="folder_id" class="col-lg-5 col-form-label text-end">Folder</label>';
$out .= '<div class="col-lg-3">';
$out .= '<select name="folder_id" id="folder_id" class="form-control">';
if ( isset( $options[0] ) ) {
$assocOptions = [];
foreach ( $options as $key => $value ) {
$assocOptions[$value] = $value;
}
$options = $assocOptions;
}
if ( ! empty( $options ) ) {
foreach ( $options as $fieldname => $value ) {
if ( $folderID == $value ) {
$selected = ' selected';
} else {
$selected = '';
}
$out .= '<option value="' . $value . '"' . $selected . '>' . $fieldname . '</option>';
}
} else {
$out .= '<option value="0" selected>No Folder</option>';
}
$out .= '</select>';
$out .= '</div>';
$out .= '</div>';
$folderSelect = Template::parse( $out );
Components::set( 'folderSelect', $folderSelect );
}
private function setPrefToggles() {
$prefsArray = [
'editModeSwitch',
'showArchivedSwitch',
'showHiddenSwitch',
'archiveButtonSwitch',
'visibilityButtonSwitch',
'privacyButtonSwitch',
'shareButtonSwitch',
'addButtonSwitch'
];
foreach ($prefsArray as $key => $name) {
if ( empty( App::$activeUser->prefs[$name] ) ) {
Components::set( $name . '_IS_CHECKED', '' );
} else {
Components::set( $name . '_IS_CHECKED', ' checked' );
}
}
}
private function setDashToggles( $current = [] ) {
$prefsArray = [
'editModeSwitch',
'showArchivedSwitch',
'showHiddenSwitch',
'archiveButtonSwitch',
'visibilityButtonSwitch',
'privacyButtonSwitch',
'shareButtonSwitch',
'addButtonSwitch'
];
foreach ( $prefsArray as $key => $name ) {
Debug::error( $name );
Debug::error( $current );
if ( ! in_array( $name, $current ) ) {
Components::set( $name . '_IS_CHECKED', '' );
} else {
Debug::error( '_IS_CHECKED' );
Components::set( $name . '_IS_CHECKED', ' checked' );
}
}
}
}

View File

@ -0,0 +1,148 @@
<?php
/**
* app/plugins/bookmarks/controllers/extensions.php
*
* This is the extensions controller.
*
* @package TP Bookmarks
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Models\Token;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Models\Folders;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Bedrock\Functions\Input;
class Extensions extends Controller {
public function index() {
self::$title = 'Browser Extensions';
self::$pageDescription = 'Our extensions cover all major browsers with the notable exception of Safari. Chrome, Opera, Brave, Firefox, and Edge are all represented; giving users a simple way to add bookmarks and folders from any page.';
if ( App::$isLoggedIn ) {
Issues::add( 'success', 'We also have a simple solution to using the app from your mobile devices <a href="/extensions/mobile">here</a>.' );
}
Views::view( 'bookmarks.extensions.index' );
}
public function mobile() {
self::$title = 'Mobile Bookmarklet';
self::$pageDescription = 'When you find yourself on the go, sometimes an extension isn\'t an option. For those times, we have the mobile bookmarklet to allow you to add bookmarks from your mobile devices.';
if ( ! App::$isLoggedIn ) {
Issues::add( 'notice', 'Since the bookmarklet is tied directly to your account, you will need to <a href="/home/login">log in</a> to generate the code for your account.' );
return Views::view( 'bookmarks.extensions.bookmarkletExplainer' );
}
if ( Input::exists('privacy') ) {
$privacy = 'const privacy = "' . Input::post('privacy') . '";';
} else {
$privacy = 'const privacy = prompt("Enter privacy level (e.g., public/private):");';
}
Components::set( 'BK_JS_PRIVACY', $privacy );
if ( Input::exists('includeDescription') ) {
$description = 'const notes = prompt("Enter a description (optional):");';
} else {
$description = '';
}
Components::set( 'BK_JS_NOTES', $description );
if ( Input::exists('includeColor') ) {
$color = 'const color = "'.Input::post('color').'";';
} else {
$color = '';
}
Components::set( 'BK_JS_COLOR', $color );
if ( Input::exists('includeFolder') ) {
$folder = 'const folder = "'.Input::post('folder_id').'";';
} else {
$folder = '';
}
Components::set( 'BK_JS_FOLDER', $folder );
$this->setFolderSelect(Input::post('folder'));
$tokens = new Token;
$apiKey = $tokens->findOrCreateUserToken( App::$activeUser->ID, true );
$apiUrl = Routes::getAddress() . 'api/bookmarks/create';
Components::set( 'BK_API_KEY', $apiKey );
Components::set( 'BK_API_URL', $apiUrl );
Views::view( 'bookmarks.extensions.bookmarklet' );
}
public function chrome() {
self::$title = 'Chrome Extension';
self::$pageDescription = 'Our Chrome extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.chrome' );
}
public function firefox() {
self::$title = 'Firefox Extension';
self::$pageDescription = 'Our Firefox extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.firefox' );
}
public function opera() {
self::$title = 'Opera Extension';
self::$pageDescription = 'Our Opera extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.opera' );
}
public function edge() {
self::$title = 'Edge Extension';
self::$pageDescription = 'Our Edge extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.edge' );
}
public function brave() {
self::$title = 'Brave Extension';
self::$pageDescription = 'Our Brave extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.brave' );
}
public function safari() {
self::$title = 'Safari Extension';
self::$pageDescription = 'Our Safari extension allows you to quickly add new bookmarks or folders right from your browser\'s toolbar.';
Views::view( 'bookmarks.extensions.safari' );
}
private function setFolderSelect( $folderID = null ) {
$folders = new Folders;
$options = $folders->simpleByUser();
$out = '';
$out .= '<select name="folder_id" id="folder_id" class="form-control">';
if ( isset( $options[0] ) ) {
$assocOptions = [];
foreach ( $options as $key => $value ) {
$assocOptions[$value] = $value;
}
$options = $assocOptions;
}
if ( ! empty( $options ) ) {
foreach ( $options as $fieldname => $value ) {
if ( $value == $folderID ) {
$selected = ' selected';
} else {
$selected = '';
}
$out .= '<option value="' . $value . '"' . $selected . '>' . $fieldname . '</option>';
}
} else {
$out .= '<option value="0" selected>No Folder</option>';
}
$out .= '</select>';
$folderSelect = Template::parse( $out );
Components::set( 'folderSelect', $folderSelect );
}
}

View File

@ -0,0 +1,107 @@
<?php
/**
* app/plugins/bookmarks/controllers/shared.php
*
* This is the bug reports controller.
*
* @package TP Bookmarks
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers;
use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Models\Bookmarks as Bookmark;
use TheTempusProject\Models\Folders;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Hermes\Functions\Route as Routes;
class Shared extends Controller {
protected static $bookmarks;
protected static $folders;
public function __construct() {
parent::__construct();
self::$bookmarks = new Bookmark;
self::$folders = new Folders;
self::$title = 'Bookmarks - {SITENAME}';
self::$pageDescription = 'Add and save url bookmarks here.';
Components::set( 'SITE_URL', Routes::getAddress() );
}
public function shared( $type = '', $id = '' ) {
if ( empty( $type ) ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
if ( empty( $id ) ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
$type = strtolower( $type );
if ( ! in_array( $type, ['link','folder'] ) ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
$this->$type( $id );
}
public function link( $id = '' ) {
if ( empty( $id ) ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
$bookmark = self::$bookmarks->findByUuid( $id );
if ( $bookmark == false ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
if ( $bookmark->createdBy != App::$activeUser->ID ) {
if ( $bookmark->privacy == 'private' ) {
if ( empty( $bookmark->folderID ) ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
$folder = self::$folders->findByUuid( $bookmark->folderID );
if ( $folder == false ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
if ( $folder->privacy == 'private' ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
}
}
return Views::view( 'bookmarks.public.bookmark', $bookmark );
}
public function folder( $id = '' ) {
if ( empty( $id ) ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
$folder = self::$folders->findByUuid( $id );
if ( $folder == false ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
if ( $folder->privacy == 'private' ) {
Session::flash( 'error', 'Unknown share' );
return Redirect::to( 'home/index' );
}
$folder->bookmarks = self::$bookmarks->unsafeByFolder( $folder->ID );
$folder->bookmarkListRows = Views::simpleView( 'bookmarks.components.publicListRows', $folder->bookmarks );
$folder->panel = Views::simpleView( 'bookmarks.components.publicList', [$folder] );
return Views::view( 'bookmarks.public.folder', $folder );
}
}

View File

@ -0,0 +1,114 @@
<?php
/**
* app/plugins/bookmarks/controllers/tutorials.php
*
* This is the tutorials controller.
*
* @package TP Bookmarks
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Houdini\Classes\Navigation;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Bedrock\Functions\Input;
class Tutorials extends Controller {
public function __construct() {
parent::__construct();
self::$title = 'Tutorials - {SITENAME}';
self::$pageDescription = 'We have detailed walkthroughs on how to perform a number of tasks for every major browser.';
}
public function index( $browser = '', $tutorial = '' ) {
return Views::view( 'bookmarks.tutorials.list' );
}
public function brave( $tutorial = '' ) {
Navigation::setCrumbComponent( 'tutorialCrumbs', Input::get( 'url' ) );
if ( ! in_array( $tutorial, ['pin','settings','import','export'] ) ) {
$test = new \stdClass();
$test->pretty = 'Brave';
$test->printed = 'brave';
return Views::view( 'bookmarks.tutorials.card', [ $test ] );
}
return Views::view( 'bookmarks.tutorials.brave.' . $tutorial );
}
public function chrome( $tutorial = '' ) {
Navigation::setCrumbComponent( 'tutorialCrumbs', Input::get( 'url' ) );
if ( ! in_array( $tutorial, ['pin','settings','import','export'] ) ) {
$test = new \stdClass();
$test->pretty = 'Chrome';
$test->printed = 'chrome';
return Views::view( 'bookmarks.tutorials.card', [ $test ] );
}
return Views::view( 'bookmarks.tutorials.chrome.' . $tutorial );
}
public function edge( $tutorial = '' ) {
Navigation::setCrumbComponent( 'tutorialCrumbs', Input::get( 'url' ) );
if ( ! in_array( $tutorial, ['pin','settings','import','export'] ) ) {
$test = new \stdClass();
$test->pretty = 'Edge';
$test->printed = 'edge';
return Views::view( 'bookmarks.tutorials.card', [ $test ] );
}
return Views::view( 'bookmarks.tutorials.edge.' . $tutorial );
}
public function opera( $tutorial = '' ) {
Navigation::setCrumbComponent( 'tutorialCrumbs', Input::get( 'url' ) );
if ( ! in_array( $tutorial, ['pin','settings','import','export'] ) ) {
$test = new \stdClass();
$test->pretty = 'Opera';
$test->printed = 'opera';
return Views::view( 'bookmarks.tutorials.card', [ $test ] );
}
return Views::view( 'bookmarks.tutorials.opera.' . $tutorial );
}
public function firefox( $tutorial = '' ) {
Navigation::setCrumbComponent( 'tutorialCrumbs', Input::get( 'url' ) );
if ( ! in_array( $tutorial, ['pin','settings','import','export'] ) ) {
$test = new \stdClass();
$test->pretty = 'Firefox';
$test->printed = 'firefox';
return Views::view( 'bookmarks.tutorials.card', [ $test ] );
}
return Views::view( 'bookmarks.tutorials.firefox.' . $tutorial );
}
public function safari( $tutorial = '' ) {
Issues::add( 'notice', 'Safari is not supported at this time.' );
return;
if ( ! in_array( $tutorial, ['pin','settings','import','export'] ) ) {
Issues::add( 'notice', 'Unknown tutorial' );
return Views::view( 'bookmarks.tutorials.list' );
}
return Views::view( 'bookmarks.tutorials.safari.' . $tutorial );
}
public function mobile( $tutorial = '' ) {
Navigation::setCrumbComponent( 'tutorialCrumbs', Input::get( 'url' ) );
if ( ! in_array( $tutorial, ['iphone','android'] ) ) {
$test = new \stdClass();
$test->pretty = 'Mobile';
$test->printed = 'mobile';
return Views::view( 'bookmarks.tutorials.mobileCard', [ $test ] );
}
return Views::view( 'bookmarks.tutorials.mobile.' . $tutorial );
}
}

View File

@ -0,0 +1,225 @@
<?php
/**
* app/plugins/bookmarks/forms.php
*
* This houses all of the form checking functions for this plugin.
*
* @package TP Bookmarks
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Plugins\Bookmarks;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Classes\Forms;
class BookmarksForms extends Forms {
/**
* Adds these functions to the form list.
*/
public function __construct() {
self::addHandler( 'createBookmark', __CLASS__, 'createBookmark' );
self::addHandler( 'createFolder', __CLASS__, 'createFolder' );
self::addHandler( 'editBookmark', __CLASS__, 'editBookmark' );
self::addHandler( 'editFolder', __CLASS__, 'editFolder' );
self::addHandler( 'importBookmarks', __CLASS__, 'importBookmarks' );
self::addHandler( 'exportBookmarks', __CLASS__, 'exportBookmarks' );
self::addHandler( 'createDashboard', __CLASS__, 'createDashboard' );
self::addHandler( 'editDashboard', __CLASS__, 'editDashboard' );
self::addHandler( 'updateDashboard', __CLASS__, 'updateDashboard' );
}
public static function createBookmark() {
// if ( ! Input::exists( 'title' ) ) {
// Check::addUserError( 'You must include a title.' );
// return false;
// }
if ( ! Input::exists( 'url' ) ) {
Check::addUserError( 'You must include a url.' );
return false;
}
// if ( ! Input::exists( 'color' ) ) {
// Check::addUserError( 'You must include a color.' );
// return false;
// }
// if ( ! Input::exists( 'privacy' ) ) {
// Check::addUserError( 'You must include a privacy.' );
// return false;
// }
// if ( !self::token() ) {
// Check::addUserError( 'token - comment out later.' );
// return false;
// }
return true;
}
public static function createFolder() {
if ( ! Input::exists( 'title' ) ) {
Check::addUserError( 'You must include a title.' );
return false;
}
// if ( ! Input::exists( 'color' ) ) {
// Check::addUserError( 'You must include a color.' );
// return false;
// }
// if ( ! Input::exists( 'privacy' ) ) {
// Check::addUserError( 'You must include a privacy.' );
// return false;
// }
// if ( ! self::token() ) {
// Check::addUserError( 'token - comment out later.' );
// return false;
// }
return true;
}
public static function editBookmark() {
// if ( ! Input::exists( 'title' ) ) {
// Check::addUserError( 'You must include a title.' );
// return false;
// }
if ( ! Input::exists( 'url' ) ) {
Check::addUserError( 'You must include a url.' );
return false;
}
// if ( ! Input::exists( 'color' ) ) {
// Check::addUserError( 'You must include a color.' );
// return false;
// }
// if ( ! Input::exists( 'privacy' ) ) {
// Check::addUserError( 'You must include a privacy.' );
// return false;
// }
// if ( !self::token() ) {
// Check::addUserError( 'token - comment out later.' );
// return false;
// }
return true;
}
public static function editFolder() {
if ( ! Input::exists( 'submit' ) ) {
return false;
}
if ( ! Input::exists( 'title' ) ) {
Check::addUserError( 'You must include a title.' );
return false;
}
// if ( ! Input::exists( 'color' ) ) {
// Check::addUserError( 'You must include a color.' );
// return false;
// }
// if ( ! Input::exists( 'privacy' ) ) {
// Check::addUserError( 'You must include a privacy.' );
// return false;
// }
// if ( !self::token() ) {
// Check::addUserError( 'token - comment out later.' );
// return false;
// }
return true;
}
public static function importBookmarks() {
if ( ! Input::exists( 'submit' ) ) {
return false;
}
// if ( ! Input::exists( 'title' ) ) {
// Check::addUserError( 'You must include a title.' );
// return false;
// }
// if ( ! Input::exists( 'color' ) ) {
// Check::addUserError( 'You must include a color.' );
// return false;
// }
// if ( ! Input::exists( 'privacy' ) ) {
// Check::addUserError( 'You must include a privacy.' );
// return false;
// }
// if ( !self::token() ) {
// Check::addUserError( 'token - comment out later.' );
// return false;
// }
return true;
}
public static function exportBookmarks() {
if ( ! Input::exists( 'submit' ) ) {
return false;
}
if ( ! Input::exists( 'BF_' ) ) {
return false;
}
// if ( ! Input::exists( 'title' ) ) {
// Check::addUserError( 'You must include a title.' );
// return false;
// }
// if ( ! Input::exists( 'color' ) ) {
// Check::addUserError( 'You must include a color.' );
// return false;
// }
// if ( ! Input::exists( 'privacy' ) ) {
// Check::addUserError( 'You must include a privacy.' );
// return false;
// }
// if ( !self::token() ) {
// Check::addUserError( 'token - comment out later.' );
// return false;
// }
return true;
}
public static function createDashboard() {
if ( ! Input::exists( 'submit' ) ) {
return false;
}
if ( ! Input::exists( 'title' ) ) {
Check::addUserError( 'You must include a title.' );
return false;
}
if ( ! Input::exists( 'link_order' ) ) {
Check::addUserError( 'You must include at least 1 link or folder.' );
return false;
}
if ( !self::token() ) {
Check::addUserError( 'There was an issue with your request.' );
return false;
}
return true;
}
public static function updateDashboard() {
if ( ! Input::exists( 'submit' ) ) {
return false;
}
if ( !self::token() ) {
Check::addUserError( 'There was an issue with your request.' );
return false;
}
return true;
}
public static function editDashboard() {
if ( ! Input::exists( 'submit' ) ) {
return false;
}
if ( ! Input::exists( 'title' ) ) {
Check::addUserError( 'You must include a title.' );
return false;
}
if ( ! Input::exists( 'link_order' ) ) {
Check::addUserError( 'You must include at least 1 link or folder.' );
return false;
}
if ( !self::token() ) {
Check::addUserError( 'There was an issue with your request.' );
return false;
}
return true;
}
}
new BookmarksForms;

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,35 @@
javascript:(function() {
const apiKey = localStorage.getItem('notAnAuthToken');
const apiUrl = localStorage.getItem('api_url');
const name = prompt("Enter a name for the bookmark:");
const notes = prompt("Enter any notes (optional):");
const color = prompt("Enter a color (optional):");
const privacy = prompt("Enter privacy level (e.g., public/private):");
const folder = prompt("Enter a folder (optional):");
const url = window.location.href;
if (!name) {
alert("Name is required.");
return;
}
fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify({ name, url, notes, color, privacy, folder })
})
.then(response => {
if (response.ok) {
alert("Bookmark saved successfully!");
} else {
alert("Failed to save bookmark. Please check your API key.");
}
})
.catch(error => {
console.error(error);
alert("An unknown error occurred while saving the bookmark.");
});
})();

View File

@ -0,0 +1,234 @@
let masonryInstance;
document.addEventListener('DOMContentLoaded', () => {
// Handle all bootstrap popover inits
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]')
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl))
// Initialize all toggle functions
toggleVisibility('editModeSwitch', 'edit-mode');
toggleVisibility('showArchivedSwitch', 'link-archived');
toggleVisibility('showHiddenSwitch', 'link-hidden');
toggleVisibility('archiveButtonSwitch', 'btn-archive');
toggleVisibility('visibilityButtonSwitch', 'btn-hideshow');
toggleVisibility('privacyButtonSwitch', 'btn-publish');
toggleVisibility('addButtonSwitch', 'btn-addlink');
toggleVisibility('shareButtonSwitch', 'btn-share');
toggleVisibility('dashShowArchivedSwitch', 'link-archived');
toggleVisibility('dashShowHiddenSwitch', 'link-hidden');
toggleVisibility('dashAddButtonSwitch', 'btn-addlink');
toggleVisibility('dashShareButtonSwitch', 'btn-share');
// Retrieve the list of collapsed folderCard IDs from local storage
const onDashboard = document.getElementById("dash_id");
let collapsedFolders;
if ( onDashboard ) {
collapsedFolders = JSON.parse(localStorage.getItem( 'collapsedDashFolders' + onDashboard.value )) || [];
} else {
collapsedFolders = JSON.parse(localStorage.getItem( 'collapsedFolders' )) || [];
}
// Collapse the elements stored in local storage when the page loads
collapsedFolders.forEach((folderId) => {
const collapseElement = document.querySelector(`#Collapse${folderId}`);
if ( collapseElement ) {
collapseElement.classList.remove('show');
}
});
// Add event listeners to track expand and collapse actions
document.querySelectorAll('.accordion-item').forEach((item) => {
const folderCardId = item.closest('.bookmark-card')?.id?.replace('folderCard', '');
if ( ! folderCardId ) return;
const collapseElement = item.querySelector('.collapse');
// Listen for collapse and expand events
collapseElement.addEventListener('hidden.bs.collapse', () => {
let storageName;
// Add the folderCard ID to local storage when collapsed
if (!collapsedFolders.includes(folderCardId)) {
collapsedFolders.push(folderCardId);
if ( onDashboard ) {
storageName = 'collapsedDashFolders' + onDashboard.value;
} else {
storageName = 'collapsedFolders';
}
localStorage.setItem( storageName , JSON.stringify(collapsedFolders));
}
});
collapseElement.addEventListener('shown.bs.collapse', () => {
let storageName;
// Remove the folderCard ID from local storage when expanded
const index = collapsedFolders.indexOf(folderCardId);
if (index > -1) {
collapsedFolders.splice(index, 1);
if ( onDashboard ) {
storageName = 'collapsedDashFolders' + onDashboard.value;
} else {
storageName = 'collapsedFolders';
}
localStorage.setItem( storageName , JSON.stringify(collapsedFolders));
}
});
});
const masonryContainer = document.getElementById("bookmarkSort");
if ( ! masonryContainer ) {
return;
}
if ( localStorage.getItem('manageFolderOrder') ) {
loadDashLinkOrder();
}
masonryInstance = new Masonry(masonryContainer, {
columnHeight: '.accordion',
itemSelector: ".bookmark-card",
percentPosition: false
});
const test = () => masonryInstance.layout();
masonryContainer.addEventListener('hidden.bs.collapse', test );
masonryContainer.addEventListener('shown.bs.collapse', test );
// Select all folder-raise and folder-lower buttons
const raiseButtons = document.querySelectorAll(".folder-raise");
const lowerButtons = document.querySelectorAll(".folder-lower");
// Function to move the folderCard up
function moveUp(event) {
const folderCard = event.target.closest(".bookmark-card");
const bookmarkSort = document.getElementById("bookmarkSort");
const orderId = document.getElementById("dashLinkOrder");
if (folderCard) {
const previousSibling = folderCard.previousElementSibling;
if (previousSibling) {
// Remove and reinsert the element before the previous sibling
bookmarkSort.removeChild(folderCard);
bookmarkSort.insertBefore(folderCard, previousSibling);
masonryInstance.reloadItems();
masonryInstance.layout();
updateDashLinkOrder();
}
}
}
// Function to move the folderCard down
function moveDown(event) {
const folderCard = event.target.closest(".bookmark-card");
const bookmarkSort = document.getElementById("bookmarkSort");
if (folderCard) {
const nextSibling = folderCard.nextElementSibling;
if (nextSibling) {
// Remove and reinsert the element after the next sibling
bookmarkSort.removeChild(folderCard);
bookmarkSort.insertBefore(folderCard, nextSibling.nextSibling);
masonryInstance.reloadItems();
masonryInstance.layout();
updateDashLinkOrder();
}
}
}
// Add event listeners to the raise buttons
raiseButtons.forEach(button => {
button.addEventListener("click", moveUp);
});
// Add event listeners to the lower buttons
lowerButtons.forEach(button => {
button.addEventListener("click", moveDown);
});
// after hiding/showing elements
masonryInstance.layout();
});
// Function to handle showing or hiding elements based on the checkbox state
function toggleVisibility(switchId, className) {
const switchElement = document.getElementById(switchId);
const elementsToToggle = document.querySelectorAll(`.${className}`);
if ( ! switchElement ) {
return;
}
// Listen for changes to the checkbox
switchElement.addEventListener('change', () => {
if (switchElement.checked) {
elementsToToggle.forEach(element => {
element.style.display = '';
});
} else {
elementsToToggle.forEach(element => {
element.style.display = 'none';
});
}
if (typeof masonryInstance !== 'undefined') {
masonryInstance.reloadItems();
masonryInstance.layout()
return;
}
});
// Trigger the toggle initially to set the correct visibility on page load
switchElement.dispatchEvent(new Event('change'));
}
function updateDashLinkOrder() {
const bookmarkCards = document.querySelectorAll("#bookmarkSort .bookmark-card");
const ids = Array.from( bookmarkCards ).map( card => {
const match = card.id.match(/folderCard(\d+)/);
return match ? match[1] : null;
}).filter( id => id !== null );
const dashLinkOrder = document.getElementById("dashLinkOrder");
if (dashLinkOrder) {
dashLinkOrder.value = ids.join(",");
} else {
localStorage.setItem('manageFolderOrder', ids.join(","));
}
}
function loadDashLinkOrder() {
const onDashboard = document.getElementById("dash_id");
const storedOrder = localStorage.getItem("manageFolderOrder"); // Get the saved order
const bookmarkSort = document.getElementById("bookmarkSort");
if ( onDashboard || !storedOrder || !bookmarkSort ) return; // Exit if no saved order or no container
const orderArray = storedOrder.split(","); // Convert the saved order into an array
const bookmarkCards = Array.from(document.querySelectorAll("#bookmarkSort .bookmark-card"));
// Create a map for quick lookup of cards by their ID
const cardMap = new Map();
bookmarkCards.forEach(card => {
const match = card.id.match(/folderCard(\d+)/);
if (match) cardMap.set(match[1], card);
});
// Reorder elements based on the saved order
const orderedElements = [];
orderArray.forEach(id => {
if (cardMap.has(id)) {
orderedElements.push(cardMap.get(id)); // Add elements in the specified order
cardMap.delete(id); // Remove from the map once processed
}
});
// Add any remaining (unspecified) elements to the end of the list
const remainingElements = Array.from(cardMap.values());
orderedElements.push(...remainingElements);
// Clear the container and append the elements in the new order
bookmarkSort.innerHTML = ""; // Remove all children
orderedElements.forEach(element => bookmarkSort.appendChild(element)); // Append in order
}

Some files were not shown because too many files have changed in this diff Show More