5.16.0 #33
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,5 @@
|
||||
# IGNORE
|
||||
.DS_Store
|
||||
*.codekit3
|
||||
.vscode
|
||||
wp-cli.phar
|
||||
/cache
|
||||
|
@ -88,6 +88,7 @@ Fires within the Fictioneer user profile section in the WordPress `wp-admin/prof
|
||||
* `fictioneer_admin_profile_fields_flags( $profile_user )` – User flags. Priority 6.
|
||||
* `fictioneer_admin_profile_fields_oauth( $profile_user )` – User OAuth connections. Priority 7.
|
||||
* `fictioneer_admin_profile_fields_data_nodes( $profile_user )` – User data nodes. Priority 8.
|
||||
* `fictioneer_admin_profile_post_unlocks( $profile_user )` - Unlock password-protected posts. Priority 9.
|
||||
* `fictioneer_admin_profile_moderation( $profile_user )` – Moderation flags and message. Priority 10.
|
||||
* `fictioneer_admin_profile_author( $profile_user )` – Author page select, support message, and support links. Priority 20.
|
||||
* `fictioneer_admin_profile_oauth( $profile_user )` – OAuth 2.0 account binding IDs. Priority 30.
|
||||
|
44
CUSTOMIZE.md
44
CUSTOMIZE.md
@ -103,6 +103,48 @@ add_filter( 'fictioneer_filter_safe_title', 'child_modify_chapter_list_title', 1
|
||||
|
||||

|
||||
|
||||
### Add prefix to chapter index list titles
|
||||
|
||||
Or change them completely, if you want even depending on the chapter or associated story. Related to [this issue](https://github.com/Tetrakern/fictioneer/issues/31). Using a filter, you can rebuild the list item HTML to your liking. In the following example, the chapter prefix has been prepended (if there is one).
|
||||
|
||||
**References**
|
||||
* Filter: [fictioneer_filter_chapter_list_item](https://github.com/Tetrakern/fictioneer/blob/main/FILTERS.md#apply_filters-fictioneer_filter_chapter_list_item-item-post-args-)
|
||||
* Include: [_helpers-templates.php](https://github.com/Tetrakern/fictioneer/blob/main/includes/functions/_helpers-templates.php)
|
||||
|
||||
```php
|
||||
/**
|
||||
* Overwrites the chapter list item string with a prefixed title
|
||||
*
|
||||
* Note: Warning, this replaces the complete string and should be
|
||||
* executed early in case there are more, less extreme filters.
|
||||
*
|
||||
* @since x.x.x
|
||||
*
|
||||
* @param string $item Original HTML string
|
||||
* @param WP_Post $post Chapter post object.
|
||||
* @param array $args Array of chapter data.
|
||||
*
|
||||
* @return string New HTML list of list item.
|
||||
*/
|
||||
|
||||
function child_prefix_chapter_index_items( $item, $post, $args ) {
|
||||
$prefix = get_post_meta( $post->ID, 'fictioneer_chapter_prefix', true );
|
||||
|
||||
return sprintf(
|
||||
'<li class="%1$s" data-id="%2$s"><a href="%3$s">%4$s<span>%5$s%6$s</span></a></li>',
|
||||
implode( ' ', $args['classes'] ),
|
||||
$post->ID,
|
||||
get_the_permalink( $post->ID ),
|
||||
$args['icon'],
|
||||
$prefix ? $prefix . ' ' : '',
|
||||
$args['list_title'] ?: $args['title']
|
||||
);
|
||||
}
|
||||
|
||||
// Priority 1 to execute the filter early
|
||||
add_filter( 'fictioneer_filter_chapter_list_item', 'child_prefix_chapter_index_items', 1, 3 );
|
||||
```
|
||||
|
||||
## Only show a specific advanced meta field
|
||||
|
||||
Maybe you want only one specific advanced meta field. You can achieve this by manually adding the desired field and saving procedure, similar to how it is done in the [_setup-meta-fields.php](https://github.com/Tetrakern/fictioneer/blob/main/includes/functions/_setup-meta-fields.php). The following example adds the Co-Authors field to stories, which can be adapted for chapters as well. Just make sure to change the {dynamic_parts} and the meta keys.
|
||||
@ -169,7 +211,7 @@ add_filter( 'fictioneer_filter_metabox_updates_story', 'child_save_co_authors_of
|
||||
|
||||
## Limit tags to 10
|
||||
|
||||
Or any other positive number for that matter. To prevent authors from entering a whole f\*\*\*ucking thesis of tags. This is not the best way, because it will just remove any tags exceeding the limit with no feedback for the author. But maybe that will teach them a lesson. Anything better needs to interfere with the Gutenberg editor and is difficult to achieve.
|
||||
Or any other positive number for that matter. To prevent authors from entering a whole f\*\*\*ing thesis of tags. This is not the best way, because it will just remove any tags exceeding the limit with no feedback for the author. But maybe that will teach them a lesson. Anything better needs to interfere with the Gutenberg editor and is difficult to achieve.
|
||||
|
||||
**References**
|
||||
* Action: [save_post](https://developer.wordpress.org/reference/hooks/save_post/)
|
||||
|
@ -221,13 +221,13 @@ Fictioneer customizes WordPress by using as many standard action and filter hook
|
||||
| `do_meta_boxes` | `fictioneer_remove_custom_fields_meta_boxes`
|
||||
| `edit_comment` | `fictioneer_comment_edit`, `fictioneer_edit_comment`
|
||||
| `edit_user_profile` | `fictioneer_custom_profile_fields`
|
||||
| `edit_user_profile_update` | `fictioneer_update_admin_user_profile`, `fictioneer_update_my_user_profile`
|
||||
| `edit_user_profile_update` | `fictioneer_update_admin_user_profile`, `fictioneer_update_my_user_profile`, `fictioneer_update_admin_unlocked_posts`
|
||||
| `get_header` | `fictioneer_maintenance_mode`
|
||||
| `init` | `fictioneer_add_character_taxonomy`, `fictioneer_add_content_warning_taxonomy`, `fictioneer_add_epub_download_endpoint`, `fictioneer_add_fandom_taxonomy`, `fictioneer_add_genre_taxonomy`, `fictioneer_add_logout_endpoint`, `fictioneer_add_oauth2_endpoint`, `fictioneer_restrict_admin_panel`, `fictioneer_disable_heartbeat`, `fictioneer_fcn_chapter_post_type`, `fictioneer_fcn_collection_post_type`, `fictioneer_fcn_recommendation_post_type`, `fictioneer_fcn_story_post_type`, `fictioneer_modify_allowed_tags`, `fictioneer_story_rss`, `fictioneer_remove_custom_fields_supports`, `fictioneer_add_sitemap_rewrite_rule`
|
||||
| `init` | `fictioneer_add_character_taxonomy`, `fictioneer_add_content_warning_taxonomy`, `fictioneer_add_epub_download_endpoint`, `fictioneer_add_fandom_taxonomy`, `fictioneer_add_genre_taxonomy`, `fictioneer_add_logout_endpoint`, `fictioneer_add_oauth2_endpoint`, `fictioneer_restrict_admin_panel`, `fictioneer_disable_heartbeat`, `fictioneer_fcn_chapter_post_type`, `fictioneer_fcn_collection_post_type`, `fictioneer_fcn_recommendation_post_type`, `fictioneer_fcn_story_post_type`, `fictioneer_modify_allowed_tags`, `fictioneer_story_rss`, `fictioneer_remove_custom_fields_supports`, `fictioneer_add_sitemap_rewrite_rule`, `fictioneer_fast_ajax`
|
||||
| `login_form` | `fictioneer_after_logout_cleanup`
|
||||
| `login_head` | `fictioneer_wp_login_scripts`
|
||||
| `manage_comments_custom_column` | `fictioneer_add_comments_report_column_content`
|
||||
| `personal_options_update` | `fictioneer_update_admin_user_profile`, `fictioneer_update_my_user_profile`
|
||||
| `personal_options_update` | `fictioneer_update_admin_user_profile`, `fictioneer_update_my_user_profile`, `fictioneer_update_admin_unlocked_posts`
|
||||
| `pre_get_posts` | `fictioneer_extend_search_query`, `fictioneer_read_others_files`, `fictioneer_read_others_files_list_view`, `fictioneer_filter_chapters_by_story`
|
||||
| `private_to_draft` | `fictioneer_chapter_to_draft`
|
||||
| `profile_update` | `fictioneer_on_profile_change`
|
||||
@ -242,7 +242,7 @@ Fictioneer customizes WordPress by using as many standard action and filter hook
|
||||
| `trashed_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_transients`, `fictioneer_remove_chapter_from_story`
|
||||
| `untrash_post` | `fictioneer_refresh_post_caches`, `fictioneer_track_chapter_and_story_updates`, `fictioneer_update_modified_date_on_story_for_chapter`, `fictioneer_purge_transients`
|
||||
| `update_option_*` | `fictioneer_update_option_disable_extended_chapter_list_meta_queries`, `fictioneer_update_option_disable_extended_story_list_meta_queries`
|
||||
| `wp_ajax_*` | `fictioneer_ajax_clear_my_checkmarks`, `fictioneer_ajax_clear_my_comments`, `fictioneer_ajax_clear_my_comment_subscriptions`, `fictioneer_ajax_clear_my_follows`, `fictioneer_ajax_clear_my_reminders`, `fictioneer_ajax_delete_epub`, `fictioneer_ajax_delete_my_account`, `fictioneer_ajax_delete_my_comment`, `fictioneer_ajax_edit_comment`, `fictioneer_ajax_get_avatar`, `fictioneer_ajax_get_comment_form`, `fictioneer_ajax_get_comment_section`, `fictioneer_ajax_get_finished_checkmarks_list`, `fictioneer_ajax_get_follows_list`, `fictioneer_ajax_get_follows_notifications`, `fictioneer_ajax_get_reminders_list`, `fictioneer_ajax_mark_follows_read`, `fictioneer_ajax_moderate_comment`, `fictioneer_ajax_report_comment`, `fictioneer_ajax_save_bookmarks`, `fictioneer_ajax_set_checkmark`, `fictioneer_ajax_submit_comment`, `fictioneer_ajax_toggle_follow`, `fictioneer_ajax_toggle_reminder`, `fictioneer_ajax_unset_my_oauth`, `fictioneer_ajax_get_user_data`, `fictioneer_ajax_get_auth`, `fictioneer_ajax_purge_schema`, `fictioneer_ajax_purge_all_schemas`, `fictioneer_ajax_reset_theme_colors`
|
||||
| `wp_ajax_*` | `fictioneer_ajax_clear_my_checkmarks`, `fictioneer_ajax_clear_my_comments`, `fictioneer_ajax_clear_my_comment_subscriptions`, `fictioneer_ajax_clear_my_follows`, `fictioneer_ajax_clear_my_reminders`, `fictioneer_ajax_delete_epub`, `fictioneer_ajax_delete_my_account`, `fictioneer_ajax_delete_my_comment`, `fictioneer_ajax_edit_comment`, `fictioneer_ajax_get_avatar`, `fictioneer_ajax_get_comment_form`, `fictioneer_ajax_get_comment_section`, `fictioneer_ajax_get_finished_checkmarks_list`, `fictioneer_ajax_get_follows_list`, `fictioneer_ajax_get_follows_notifications`, `fictioneer_ajax_get_reminders_list`, `fictioneer_ajax_mark_follows_read`, `fictioneer_ajax_moderate_comment`, `fictioneer_ajax_report_comment`, `fictioneer_ajax_save_bookmarks`, `fictioneer_ajax_set_checkmark`, `fictioneer_ajax_submit_comment`, `fictioneer_ajax_toggle_follow`, `fictioneer_ajax_toggle_reminder`, `fictioneer_ajax_unset_my_oauth`, `fictioneer_ajax_get_user_data`, `fictioneer_ajax_get_auth`, `fictioneer_ajax_purge_schema`, `fictioneer_ajax_purge_all_schemas`, `fictioneer_ajax_reset_theme_colors`, `fictioneer_ajax_search_posts_to_unlock`
|
||||
| `wp_ajax_nopriv_*` | `fictioneer_ajax_get_comment_form`, `fictioneer_ajax_get_comment_section`, `fictioneer_ajax_submit_comment`, `fictioneer_ajax_get_auth`
|
||||
| `wp_before_admin_bar_render` | `fictioneer_remove_admin_bar_links`, `fictioneer_remove_dashboard_from_admin_bar`, `fictioneer_remove_comments_from_admin_bar`
|
||||
| `wp_dashboard_setup` | `fictioneer_remove_dashboard_widgets`
|
||||
|
@ -288,7 +288,7 @@ This notice appears above the title if you add a chapter warning, not to be conf
|
||||
| Excerpt | Text | Chapter excerpt used in cards. If empty, part of the content will be used.
|
||||
| Icon | String | Free [Font Awesome](https://fontawesome.com/search) class string. Defaults to `fa-solid fa-book`.
|
||||
| Text Icon (A) | String | Overrides icon with a text string, good for combining with symbol fonts.
|
||||
| Short Title (A) | String | Optional short chapter title, intended to be used in child themes.
|
||||
| Short Title (A) | String | Optional short chapter title, not used by default (intended for child themes).
|
||||
| Prefix (A) | String | Prepended to the title in chapter lists. Not used in generated ePUBs.
|
||||
| Co-Authors (A) | List | List of co-authors. They must be registered users, but dummies will do.
|
||||
| Age Rating | Select | Choose between everyone, teen, mature, and adult.
|
||||
@ -301,6 +301,16 @@ This notice appears above the title if you add a chapter warning, not to be conf
|
||||
|
||||
<sup>**(A)** for Advanced: These meta fields are hidden unless you check the "Enable advanced meta fields" option under **Fictioneer > General > Compatibility.** Most sites just do not need these.</sup>
|
||||
|
||||
### Chapter Titles
|
||||
|
||||
As you can take away from the meta fields, there are several optional chapter titles and title-related fields. This can be confusing, so here is where and how these fields are actually used. Blank fields are obviously not rendered.
|
||||
|
||||
* **Small Cards (Shortcodes):** List Title *or* Title
|
||||
* **Large Chapter Cards (List Templates):** Title *and* List Title (on mobile)
|
||||
* **Large Story Cards (List Templates):** List Title *or* Title
|
||||
* **Chapter Index (Popup/Mobile):** List Title *or* Title
|
||||
* **Chapter Lists (Story/Shortcode):** Prefix + Title
|
||||
|
||||
### Text-To-Speech Engine
|
||||
|
||||
Must be enabled in the settings and is started from the paragraph tools. Makes use of the free [Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API) that all modern browsers support, which can be wonky at times but produces surprisingly decent results. Primarily meant as accessibility feature for the reading-impaired. Absolutely _not_ fail-proof and depends on the browser and operating system; additional permissions may be necessary on the playback device (this is outside your control).
|
||||
@ -536,6 +546,14 @@ You can grant logged-in users access to password-protected content via Patreon m
|
||||
|
||||
**Free Tier:** If you want to gate content behind the free tier (only following, not paying), you can just add the tier alongside the others. If that is too inconvenient because you got too many tiers, you can use the pledge threshold to include any tier equal to or above a certain amount in cents (e.g. 300 for $3.00), either globally or post by post.
|
||||
|
||||
## Unlock Posts
|
||||
|
||||
You can grant logged-in users access to password-protected content by unlocking specific posts. Just open the admin profile page of the user, search for the posts you want to unlock, add them and save. Chapters inherit the unlock of the story. Roles other than administrators require both the **Edit Users** and **Unlock Posts** capabilities to unlock posts, which can be assigned in the role manager.
|
||||
|
||||
**Patreon Gate:** Post unlocks are normally independent of Patreon, but you can gate them behind a global pledge threshold in cents to limit the feature to paying patrons only. This is in addition to any other Patreon gates.
|
||||
|
||||

|
||||
|
||||
## Shortcodes
|
||||
|
||||
[Shortcodes](https://wordpress.org/support/article/shortcode-block/) are bracket-enclosed keywords placed within the content that WordPress automatically interprets into code, adding features or objects without the need for programming. This should be done inside a _shortcode_ block, although it would work outside too. Since most elements created by shortcodes have no margins, the _spacer_ block can be a good addition before and/or after.
|
||||
|
15
FILTERS.md
15
FILTERS.md
@ -183,6 +183,21 @@ Filters the intermediate output array in the `_chapter-header.php` partial befor
|
||||
|
||||
---
|
||||
|
||||
### `apply_filters( 'fictioneer_filter_chapter_list_item', $item, $post, $args )`
|
||||
Filters each list item HTML string used in the chapter index popup and mobile menu section (only visible on chapter pages), build inside the `fictioneer_get_chapter_list_items()` function. Not to be confused with the chapter list shown on story pages. You can either modify the string or build a new one from the given parameters.
|
||||
|
||||
**Parameters:**
|
||||
* $item (string) – HTML for the list item with icon, ID, link, and title.
|
||||
* $post (WP_Post) - The chapter post object.
|
||||
|
||||
**$args:**
|
||||
* $title (string) – HTML for the regular title.
|
||||
* $list_title (string) – HTML for the list title or empty.
|
||||
* $icon (string) – HTML for the (text) icon or empty.
|
||||
* $classes (array) – Array of CSS classes or empty.
|
||||
|
||||
---
|
||||
|
||||
### `apply_filters( 'fictioneer_filter_chapter_micro_menu', $micro_menu, $args )`
|
||||
Filters the intermediate output array of the chapter micro menu in the `fictioneer_get_chapter_micro_menu( $args )` function before it is imploded and rendered.
|
||||
|
||||
|
@ -596,6 +596,7 @@ The integrated role manager to add and, edit, and remove roles. Not the most sop
|
||||
* **Read Others Files:** Allows you to see uploaded files from *other* users.
|
||||
* **Edit Others Files:** Allows you to edit uploaded files from *other* users.
|
||||
* **Delete Others Files:** Allows you to delete uploaded files from *other* users.
|
||||
* **Unlock Posts:** Allows you to unlock selected password-protected posts for users.
|
||||
* **Manage {Taxonomy}:** Lets you see the overview list table of the taxonomy.
|
||||
* **Assign {Taxonomy}:** Lets you assign the taxonomy to your posts.
|
||||
* **Edit {Taxonomy}:** Lets you create and edit taxonomies of this type.
|
||||
@ -683,6 +684,7 @@ Once you are done, you can apply tiers and pledge thresholds in cents (e.g. 350
|
||||
* **Tiers (Post/Global):** Comma-separated list of tier IDs, which you can see after pulling them.
|
||||
* **Threshold (Post/Global):** Pledge amount in cents (e.g. 350 for $3.50) independent of tiers.
|
||||
* **Lifetime Threshold (Global):** Use the total of all paid pledges, regardless of current status.
|
||||
* **Unlock Threshold (Global):** Gate regular user post unlocks behind a pledge amount in cents.
|
||||
|
||||
Membership data is valid for one week by default, per user, refreshed whenever they log in with Patreon. This can cause users to retain access rights for longer than their membership status allows (up to six days), which is a consequence of the theme not keeping a continuous connection to Patreon for security reasons — but if you get hacked, their Patreon accounts will be safe in turn. Security is rarely convenient.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<p align="center"><img src="./repo/assets/fictioneer_logo.svg?raw=true" alt="Fictioneer"></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/Tetrakern/fictioneer"><img alt="Theme: 5.15" src="https://img.shields.io/badge/theme-5.15-blue?style=flat" /></a>
|
||||
<a href="https://github.com/Tetrakern/fictioneer"><img alt="Theme: 5.16" src="https://img.shields.io/badge/theme-5.16-blue?style=flat" /></a>
|
||||
<a href="LICENSE.md"><img alt="License: GPL v3" src="https://img.shields.io/badge/license-GPL%20v3-blue?style=flat" /></a>
|
||||
<a href="https://wordpress.org/download/"><img alt="WordPress 6.1+" src="https://img.shields.io/badge/WordPress-%3E%3D6.1-blue?style=flat" /></a>
|
||||
<a href="https://www.php.net/"><img alt="PHP: 7.4+" src="https://img.shields.io/badge/php-%3E%3D7.4-blue?logoColor=white&style=flat" /></a>
|
||||
@ -35,7 +35,7 @@ stories, chapters, collections, and recommendations • customizable web read
|
||||
|
||||
## Support the Development
|
||||
|
||||
Fictioneer (up to 5.15) has been developed by one author, barring [credited](CREDITS.md) code snippets. This was an exhausting effort and is not sustainable, so any help going forward is appreciated. If you are interested, or want to fork your own version, take a look at the [development](DEVELOPMENT.md) guidelines, [action](ACTIONS.md) hooks, and [filter](FILTERS.md) hooks. A theme-related base plugin can be found [here](https://github.com/Tetrakern/fictioneer-base-plugin). You can also join the [Discord](https://discord.gg/tVfDB7EbaP).
|
||||
Fictioneer (up to 5.16) has been developed by one author, barring [credited](CREDITS.md) code snippets. This was an exhausting effort and is not sustainable, so any help going forward is appreciated. If you are interested, or want to fork your own version, take a look at the [development](DEVELOPMENT.md) guidelines, [action](ACTIONS.md) hooks, and [filter](FILTERS.md) hooks. A theme-related base plugin can be found [here](https://github.com/Tetrakern/fictioneer-base-plugin). You can also join the [Discord](https://discord.gg/tVfDB7EbaP).
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
5845
config.codekit3
Normal file
5845
config.codekit3
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -32,9 +32,9 @@ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
||||
// =============================================================================
|
||||
|
||||
// Version
|
||||
define( 'FICTIONEER_VERSION', '5.15.2' );
|
||||
define( 'FICTIONEER_VERSION', '5.16.0' );
|
||||
define( 'FICTIONEER_MAJOR_VERSION', '5' );
|
||||
define( 'FICTIONEER_RELEASE_TAG', 'v5.15.2' );
|
||||
define( 'FICTIONEER_RELEASE_TAG', 'v5.16.0' );
|
||||
|
||||
if ( ! defined( 'CHILD_VERSION' ) ) {
|
||||
define( 'CHILD_VERSION', null );
|
||||
@ -413,16 +413,6 @@ if ( ! defined( 'FICTIONEER_EXAMPLE_CHAPTER_ICONS' ) ) {
|
||||
);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// FAST REQUESTS
|
||||
//
|
||||
// This is significantly faster than even the REST API because it skips most of
|
||||
// the theme initialization and the init() action. However, this also means you
|
||||
// cannot use any actions and filters not loaded at this point.
|
||||
// =============================================================================
|
||||
|
||||
require_once __DIR__ . '/includes/functions/_fast-requests.php';
|
||||
|
||||
// =============================================================================
|
||||
// GLOBAL
|
||||
// =============================================================================
|
||||
|
@ -1,274 +0,0 @@
|
||||
<?php
|
||||
|
||||
// =============================================================================
|
||||
// FAST AJAX REQUESTS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! defined( 'FICTIONEER_FAST_AJAX_FUNCTIONS' ) ) {
|
||||
define(
|
||||
'FICTIONEER_FAST_AJAX_FUNCTIONS',
|
||||
array(
|
||||
// Bookmarks
|
||||
'fictioneer_ajax_save_bookmarks',
|
||||
// Follows
|
||||
'fictioneer_ajax_toggle_follow',
|
||||
'fictioneer_ajax_clear_my_follows',
|
||||
'fictioneer_ajax_mark_follows_read',
|
||||
'fictioneer_ajax_get_follows_notifications',
|
||||
'fictioneer_ajax_get_follows_list',
|
||||
// Reminders
|
||||
'fictioneer_ajax_toggle_reminder',
|
||||
'fictioneer_ajax_clear_my_reminders',
|
||||
'fictioneer_ajax_get_reminders_list',
|
||||
// Checkmarks
|
||||
'fictioneer_ajax_set_checkmark',
|
||||
'fictioneer_ajax_clear_my_checkmarks',
|
||||
'fictioneer_ajax_get_finished_checkmarks_list',
|
||||
// User
|
||||
'fictioneer_ajax_get_auth',
|
||||
'fictioneer_ajax_get_user_data',
|
||||
'fictioneer_ajax_get_avatar',
|
||||
// Admin
|
||||
'fictioneer_ajax_query_relationship_posts',
|
||||
// Plugins
|
||||
'fictioneer_ajax_fcnen_search_content',
|
||||
'fictioneer_ajax_fcnen_get_form_content',
|
||||
'fictioneer_ajax_fcnen_subscribe_or_update',
|
||||
'fictioneer_ajax_fcnen_unsubscribe',
|
||||
'fictioneer_ajax_fcnen_process_email_queue'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an AJAX action before initialization
|
||||
*
|
||||
* Fires after the theme constants have been defined, but skips
|
||||
* everything after that is not required by the action. Child
|
||||
* themes are not called and custom actions/filters not loaded.
|
||||
* Any customization must happen in a must-use plugin or the
|
||||
* config.php (which is bad practice).
|
||||
*
|
||||
* @since 5.6.3
|
||||
*/
|
||||
|
||||
function fictioneer_do_fast_ajax() {
|
||||
$action = sanitize_text_field( $_REQUEST['action'] );
|
||||
|
||||
// Allowed action?
|
||||
if (
|
||||
! in_array( $action, FICTIONEER_FAST_AJAX_FUNCTIONS, true ) ||
|
||||
strpos( $action, 'fictioneer_ajax' ) !== 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Include required files
|
||||
require_once __DIR__ . '/_utility.php';
|
||||
require_once __DIR__ . '/_helpers-query.php';
|
||||
require_once __DIR__ . '/_service-caching.php';
|
||||
require_once __DIR__ . '/_setup-types-and-terms.php';
|
||||
|
||||
if ( get_option( 'fictioneer_enable_follows' ) && strpos( $action, '_follow' ) !== false ) {
|
||||
require_once __DIR__ . '/_helpers-templates.php';
|
||||
require_once __DIR__ . '/users/_follows.php';
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_reminders' ) && strpos( $action, '_reminder' ) !== false ) {
|
||||
require_once __DIR__ . '/_helpers-templates.php';
|
||||
require_once __DIR__ . '/users/_reminders.php';
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_checkmarks' ) && strpos( $action, '_checkmark' ) !== false ) {
|
||||
require_once __DIR__ . '/_helpers-templates.php';
|
||||
require_once __DIR__ . '/users/_checkmarks.php';
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_bookmarks' ) && strpos( $action, '_bookmarks' ) !== false ) {
|
||||
require_once __DIR__ . '/users/_bookmarks.php';
|
||||
}
|
||||
|
||||
if ( strpos( $action, 'get_user_data' ) !== false ) {
|
||||
require_once __DIR__ . '/users/_user_data.php';
|
||||
require_once __DIR__ . '/users/_follows.php';
|
||||
require_once __DIR__ . '/users/_reminders.php';
|
||||
require_once __DIR__ . '/users/_checkmarks.php';
|
||||
require_once __DIR__ . '/users/_bookmarks.php';
|
||||
require_once __DIR__ . '/_helpers-templates.php';
|
||||
}
|
||||
|
||||
if ( strpos( $action, '_list' ) !== false ) {
|
||||
require_once __DIR__ . '/_setup-wordpress.php';
|
||||
}
|
||||
|
||||
if ( strpos( $action, '_fingerprint' ) !== false ) {
|
||||
require_once __DIR__ . '/users/_user_data.php';
|
||||
}
|
||||
|
||||
if ( strpos( $action, '_avatar' ) !== false ) {
|
||||
require_once __DIR__ . '/users/_avatars.php';
|
||||
}
|
||||
|
||||
// Register custom post types and taxonomies
|
||||
fictioneer_register_cpt_and_tax();
|
||||
|
||||
// Skip cache checks
|
||||
if ( ! function_exists( 'fictioneer_caching_active' ) ) {
|
||||
function fictioneer_caching_active( $context = null ) { return false; };
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'fictioneer_private_caching_active' ) ) {
|
||||
function fictioneer_private_caching_active() { return false; };
|
||||
}
|
||||
|
||||
// Skip cache purging
|
||||
if ( ! function_exists( 'fictioneer_refresh_post_caches' ) ) {
|
||||
function fictioneer_refresh_post_caches() { return; };
|
||||
}
|
||||
|
||||
if ( $action === 'fictioneer_ajax_query_relationship_posts' ) {
|
||||
require_once __DIR__ . '/_helpers-templates.php';
|
||||
require_once __DIR__ . '/_setup-admin.php';
|
||||
}
|
||||
|
||||
if ( $action === 'fictioneer_ajax_fcnen_search_content' ) {
|
||||
require_once __DIR__ . '/_helpers-templates.php';
|
||||
}
|
||||
|
||||
// Function exists?
|
||||
if ( ! function_exists( $action ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call function
|
||||
call_user_func( $action );
|
||||
|
||||
// Terminate in case something goes wrong
|
||||
die();
|
||||
}
|
||||
|
||||
if (
|
||||
defined( 'DOING_AJAX' ) && DOING_AJAX &&
|
||||
isset( $_REQUEST['fcn_fast_ajax'] ) &&
|
||||
isset( $_REQUEST['action'] )
|
||||
) {
|
||||
fictioneer_do_fast_ajax();
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// FAST AJAX COMMENT REQUESTS
|
||||
// =============================================================================
|
||||
|
||||
if ( ! defined( 'FICTIONEER_FAST_AJAX_COMMENT_FUNCTIONS' ) ) {
|
||||
define(
|
||||
'FICTIONEER_FAST_AJAX_COMMENT_FUNCTIONS',
|
||||
array(
|
||||
'fictioneer_ajax_delete_my_comment',
|
||||
'fictioneer_ajax_moderate_comment',
|
||||
'fictioneer_ajax_report_comment',
|
||||
'fictioneer_ajax_get_comment_form',
|
||||
'fictioneer_ajax_get_comment_section',
|
||||
'fictioneer_ajax_submit_comment',
|
||||
'fictioneer_ajax_edit_comment'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an AJAX comment action before initialization
|
||||
*
|
||||
* Fires after the theme constants have been defined, but skips
|
||||
* everything after that is not required by the action. Child
|
||||
* themes are not called and custom actions/filters not loaded.
|
||||
* Any customization must happen in a must-use plugin or the
|
||||
* config.php (which is bad practice).
|
||||
*
|
||||
* @since 5.6.3
|
||||
*/
|
||||
|
||||
function fictioneer_do_fast_comment_ajax() {
|
||||
$action = sanitize_text_field( $_REQUEST['action'] );
|
||||
|
||||
// Allowed action?
|
||||
if ( ! in_array( $action, FICTIONEER_FAST_AJAX_COMMENT_FUNCTIONS, true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Include required files
|
||||
require_once __DIR__ . '/_utility.php'; // Obviously
|
||||
require_once __DIR__ . '/_setup-wordpress.php'; // Depends
|
||||
require_once __DIR__ . '/_setup-roles.php'; // Depends
|
||||
require_once __DIR__ . '/_service-caching.php'; // Maybe?
|
||||
require_once __DIR__ . '/_helpers-templates.php'; // Safe title
|
||||
require_once __DIR__ . '/comments/_comments_controller.php'; // Obviously
|
||||
require_once __DIR__ . '/comments/_comments_moderation.php'; // Obviously
|
||||
require_once __DIR__ . '/comments/_comments_ajax.php'; // Obviously
|
||||
|
||||
// Moderating needs less, otherwise include everything related to comments
|
||||
if ( strpos( $action, '_moderate_comment' ) === false ) {
|
||||
require_once __DIR__ . '/_module-discord.php'; // Notifications
|
||||
require_once __DIR__ . '/_setup-types-and-terms.php'; // Depends
|
||||
require_once __DIR__ . '/_module-oauth.php'; // Login buttons
|
||||
require_once __DIR__ . '/users/_user_data.php'; // Obviously
|
||||
require_once __DIR__ . '/users/_avatars.php'; // Obviously
|
||||
require_once __DIR__ . '/comments/_comments_form.php'; // Obviously
|
||||
require_once __DIR__ . '/comments/_comments_threads.php'; // Obviously
|
||||
|
||||
// Register custom post types and taxonomies
|
||||
fictioneer_register_cpt_and_tax();
|
||||
}
|
||||
|
||||
// Function exists?
|
||||
if ( ! function_exists( $action ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call function
|
||||
call_user_func( $action );
|
||||
|
||||
// Terminate in case something goes wrong
|
||||
die();
|
||||
}
|
||||
|
||||
if (
|
||||
get_option( 'fictioneer_enable_fast_ajax_comments' ) &&
|
||||
defined( 'DOING_AJAX' ) && DOING_AJAX &&
|
||||
strpos( $_REQUEST['action'] ?? '', 'fictioneer_ajax' ) === 0 &&
|
||||
strpos( $_REQUEST['action'] ?? '', 'comment' ) !== false
|
||||
) {
|
||||
fictioneer_do_fast_comment_ajax();
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// FAST AJAX STORY COMMENTS REQUESTS
|
||||
// =============================================================================
|
||||
|
||||
// Fast REST request to get story comments
|
||||
if (
|
||||
get_option( 'fictioneer_enable_fast_ajax_comments' ) &&
|
||||
strpos( $_SERVER['REQUEST_URI'], 'wp-json/fictioneer/v1/get_story_comments' ) !== false
|
||||
) {
|
||||
// Include required files
|
||||
require_once __DIR__ . '/_utility.php';
|
||||
require_once __DIR__ . '/_setup-wordpress.php';
|
||||
require_once __DIR__ . '/_setup-roles.php';
|
||||
require_once __DIR__ . '/users/_user_data.php';
|
||||
require_once __DIR__ . '/users/_avatars.php';
|
||||
require_once __DIR__ . '/comments/_comments_controller.php';
|
||||
require_once __DIR__ . '/comments/_comments_threads.php';
|
||||
require_once __DIR__ . '/comments/_story_comments.php';
|
||||
|
||||
// Build fake REST request
|
||||
$rest_request = new WP_REST_Request( 'GET', 'fictioneer/v1/get_story_comments' );
|
||||
$rest_request->set_param( 'post_id', absint( $_REQUEST['post_id'] ?? 0 ) );
|
||||
$rest_request->set_param( 'page', absint( $_REQUEST['page'] ?? 1 ) );
|
||||
|
||||
// Get comments with fake REST request
|
||||
$response = fictioneer_rest_get_story_comments( $rest_request );
|
||||
|
||||
// Extract data from WP_REST_Response
|
||||
wp_send_json( $response->get_data(), $response->get_status() );
|
||||
|
||||
// Terminate in case something goes wrong
|
||||
die();
|
||||
}
|
@ -1226,6 +1226,7 @@ if ( ! function_exists( 'fictioneer_get_chapter_list_items' ) ) {
|
||||
* @since 5.9.3 - Added meta field caching.
|
||||
* @since 5.9.4 - Removed output buffer.
|
||||
* @since 5.12.2 - Use permalinks instead of page ID.
|
||||
* @since 5.16.0 - Clean up and add filter.
|
||||
*
|
||||
* @param int $story_id ID of the story.
|
||||
* @param array $data Prepared data of the story.
|
||||
@ -1267,21 +1268,12 @@ if ( ! function_exists( 'fictioneer_get_chapter_list_items' ) ) {
|
||||
|
||||
// Prepare
|
||||
$classes = [];
|
||||
$title = trim( $chapter->post_title );
|
||||
$title = fictioneer_get_safe_title( $chapter->ID, 'get_chapter_list_items' );
|
||||
$list_title = get_post_meta( $chapter->ID, 'fictioneer_chapter_list_title', true );
|
||||
$list_title = trim( wp_strip_all_tags( $list_title ) );
|
||||
$text_icon = get_post_meta( $chapter->ID, 'fictioneer_chapter_text_icon', true );
|
||||
$icon = '';
|
||||
|
||||
// Check for empty title
|
||||
if ( empty( $title ) && empty( $list_title ) ) {
|
||||
$title = sprintf(
|
||||
_x( '%1$s — %2$s', '[Date] — [Time] if chapter title is missing.', 'fictioneer' ),
|
||||
get_the_date( '', $chapter->ID ),
|
||||
get_the_time( '', $chapter->ID )
|
||||
);
|
||||
}
|
||||
|
||||
// Mark for password
|
||||
if ( ! empty( $chapter->post_password ) ) {
|
||||
$classes[] = 'has-password';
|
||||
@ -1295,14 +1287,26 @@ if ( ! function_exists( 'fictioneer_get_chapter_list_items' ) ) {
|
||||
}
|
||||
|
||||
// HTML
|
||||
$html .= sprintf(
|
||||
'<li class="%s" data-id="%d"><a href="%s">%s<span>%s</span></a></li>',
|
||||
$item = sprintf(
|
||||
'<li class="%1$s" data-id="%2$s"><a href="%3$s">%4$s<span>%5$s</span></a></li>',
|
||||
implode( ' ', $classes ),
|
||||
$chapter->ID,
|
||||
get_the_permalink( $chapter->ID ),
|
||||
$icon,
|
||||
$list_title ?: $title
|
||||
);
|
||||
|
||||
$html .= apply_filters(
|
||||
'fictioneer_filter_chapter_list_item',
|
||||
$item,
|
||||
$chapter,
|
||||
array(
|
||||
'title' => $title,
|
||||
'list_title' => $list_title,
|
||||
'icon' => $icon,
|
||||
'classes' => $classes
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Update meta cache
|
||||
|
@ -51,10 +51,7 @@ define(
|
||||
function fictioneer_add_oauth2_endpoint() {
|
||||
add_rewrite_endpoint( FICTIONEER_OAUTH_ENDPOINT, EP_ROOT );
|
||||
}
|
||||
|
||||
if ( get_option( 'fictioneer_enable_oauth' ) ) {
|
||||
add_action( 'init', 'fictioneer_add_oauth2_endpoint', 10 );
|
||||
}
|
||||
add_action( 'init', 'fictioneer_add_oauth2_endpoint', 10 );
|
||||
|
||||
// =============================================================================
|
||||
// GET OAUTH LOGIN LINK
|
||||
|
@ -62,7 +62,7 @@ function fictioneer_admin_scripts( $hook_suffix ) {
|
||||
if ( $hook_suffix === 'post.php' || $hook_suffix === 'post-new.php' ) {
|
||||
wp_enqueue_script(
|
||||
'fictioneer-sortablejs',
|
||||
'https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js',
|
||||
get_template_directory_uri() . '/js/Sortable-1.15.2.min.js',
|
||||
['jquery', 'fictioneer-utility-scripts'],
|
||||
FICTIONEER_VERSION,
|
||||
true
|
||||
|
@ -34,7 +34,8 @@ define(
|
||||
'fcn_ignore_page_passwords',
|
||||
'fcn_ignore_fcn_story_passwords',
|
||||
'fcn_ignore_fcn_chapter_passwords',
|
||||
'fcn_ignore_fcn_collection_passwords'
|
||||
'fcn_ignore_fcn_collection_passwords',
|
||||
'fcn_unlock_posts'
|
||||
)
|
||||
);
|
||||
|
||||
@ -95,9 +96,10 @@ function fictioneer_initialize_roles( $force = false ) {
|
||||
}
|
||||
|
||||
// If this capability is missing, the roles need to be updated
|
||||
if ( $administrator && ! in_array( 'fcn_custom_epub_upload', array_keys( $administrator->capabilities ) ) ) {
|
||||
if ( $administrator && ! in_array( 'fcn_unlock_posts', array_keys( $administrator->capabilities ) ) ) {
|
||||
get_role( 'administrator' )->add_cap( 'fcn_custom_page_header' );
|
||||
get_role( 'administrator' )->add_cap( 'fcn_custom_epub_upload' );
|
||||
get_role( 'administrator' )->add_cap( 'fcn_unlock_posts' );
|
||||
|
||||
if ( $editor = get_role( 'editor' ) ) {
|
||||
$editor->add_cap( 'fcn_custom_page_header' );
|
||||
@ -435,6 +437,7 @@ if ( ! defined( 'FICTIONEER_ALLOWED_PAGE_TEMPLATES' ) ) {
|
||||
*
|
||||
* @since 5.12.3
|
||||
* @since 5.15.0 - Add Patreon checks.
|
||||
* @since 5.16.0 - Add Patreon unlock checks and static variable cache.
|
||||
*
|
||||
* @param bool $required Whether the user needs to supply a password.
|
||||
* @param WP_Post $post Post object.
|
||||
@ -443,13 +446,26 @@ if ( ! defined( 'FICTIONEER_ALLOWED_PAGE_TEMPLATES' ) ) {
|
||||
*/
|
||||
|
||||
function fictioneer_bypass_password( $required, $post ) {
|
||||
// Static variable cache
|
||||
static $cache = [];
|
||||
|
||||
$cache_key = $post->ID . '_' . (int) $required;
|
||||
|
||||
if ( isset( $cache[ $cache_key ] ) ) {
|
||||
return $cache[ $cache_key ];
|
||||
}
|
||||
|
||||
// Already passed
|
||||
if ( ! $required ) {
|
||||
$cache[ $cache_key ] = $required;
|
||||
|
||||
return $required;
|
||||
}
|
||||
|
||||
// Always allow admins
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
$cache[ $cache_key ] = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -504,6 +520,35 @@ function fictioneer_bypass_password( $required, $post ) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check unlocked posts
|
||||
if ( $user && $required ) {
|
||||
$story_id = get_post_meta( $post->ID, 'fictioneer_chapter_story', true );
|
||||
$unlocks = get_user_meta( $user->ID, 'fictioneer_post_unlocks', true ) ?: [];
|
||||
$unlocks = is_array( $unlocks ) ? $unlocks : [];
|
||||
$patreon_gate_amount = get_option( 'fictioneer_patreon_global_lock_unlock_amount', 0 ) ?: 0;
|
||||
$allow_unlocks = ! ( get_option( 'fictioneer_enable_patreon_locks' ) && $patreon_gate_amount );
|
||||
|
||||
// Check Patreon unlock gate
|
||||
if ( ! $allow_unlocks ) {
|
||||
$patreon_user_tiers = get_user_meta( $user->ID, 'fictioneer_patreon_tiers', true );
|
||||
$patreon_user_tiers = is_array( $patreon_user_tiers ) ? $patreon_user_tiers : [];
|
||||
|
||||
foreach ( $patreon_user_tiers as $tier ) {
|
||||
if ( ( $tier['amount_cents'] ?? -1 ) >= $patreon_gate_amount ) {
|
||||
$allow_unlocks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $allow_unlocks && $unlocks && array_intersect( [ $post->ID, $story_id ], $unlocks ) ) {
|
||||
$required = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache
|
||||
$cache[ $cache_key ] = $required;
|
||||
|
||||
// Continue filter
|
||||
return $required;
|
||||
}
|
||||
@ -544,11 +589,7 @@ if ( ! current_user_can( 'manage_options' ) ) {
|
||||
}
|
||||
|
||||
// Redirect back to Home
|
||||
if (
|
||||
is_admin() &&
|
||||
// ! ( defined( 'DOING_AJAX' ) && DOING_AJAX )
|
||||
! current_user_can( 'fcn_admin_panel_access' )
|
||||
) {
|
||||
if ( is_admin() && ! current_user_can( 'fcn_admin_panel_access' ) ) {
|
||||
wp_redirect( home_url() );
|
||||
exit;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
function fictioneer_bring_out_legacy_trash() {
|
||||
// Setup
|
||||
$options = wp_cache_get( 'alloptions', 'options' );
|
||||
$obsolete = ['fictioneer_disable_html_in_comments', 'fictioneer_block_subscribers_from_admin', 'fictioneer_admin_restrict_menus', 'fictioneer_admin_restrict_private_data', 'fictioneer_admin_reduce_subscriber_profile', 'fictioneer_enable_subscriber_self_delete', 'fictioneer_strip_shortcodes_for_non_administrators', 'fictioneer_restrict_media_access', 'fictioneer_subscription_enabled', 'fictioneer_patreon_badge_map', 'fictioneer_patreon_tier_as_badge', 'fictioneer_patreon_campaign_ids', 'fictioneer_patreon_campaign_id', 'fictioneer_mount_wpdiscuz_theme_styles', 'fictioneer_base_site_width', 'fictioneer_comment_form_selector', 'fictioneer_featherlight_enabled', 'fictioneer_tts_enabled', 'fictioneer_log', 'fictioneer_enable_ajax_nonce', 'fictioneer_flush_object_cache', 'fictioneer_enable_all_block_styles', 'fictioneer_light_mode_as_default'];
|
||||
$obsolete = ['fictioneer_disable_html_in_comments', 'fictioneer_block_subscribers_from_admin', 'fictioneer_admin_restrict_menus', 'fictioneer_admin_restrict_private_data', 'fictioneer_admin_reduce_subscriber_profile', 'fictioneer_enable_subscriber_self_delete', 'fictioneer_strip_shortcodes_for_non_administrators', 'fictioneer_restrict_media_access', 'fictioneer_subscription_enabled', 'fictioneer_patreon_badge_map', 'fictioneer_patreon_tier_as_badge', 'fictioneer_patreon_campaign_ids', 'fictioneer_patreon_campaign_id', 'fictioneer_mount_wpdiscuz_theme_styles', 'fictioneer_base_site_width', 'fictioneer_featherlight_enabled', 'fictioneer_tts_enabled', 'fictioneer_log', 'fictioneer_enable_ajax_nonce', 'fictioneer_flush_object_cache', 'fictioneer_enable_all_block_styles', 'fictioneer_light_mode_as_default'];
|
||||
|
||||
// Check for most recent obsolete option...
|
||||
if ( isset( $options['fictioneer_light_mode_as_default'] ) ) {
|
||||
@ -741,7 +741,7 @@ function fictioneer_output_customize_css() {
|
||||
wp_enqueue_style(
|
||||
'fictioneer-customize',
|
||||
get_template_directory_uri() . "/cache/customize.css?timestamp={$last_built_timestamp}",
|
||||
['fictioneer-application'],
|
||||
get_option( 'fictioneer_bundle_stylesheets' ) ? ['fictioneer-complete'] : ['fictioneer-application'],
|
||||
fictioneer_get_cache_bust()
|
||||
);
|
||||
}
|
||||
@ -1402,7 +1402,7 @@ if ( ! function_exists( 'fictioneer_output_head_critical_scripts' ) ) {
|
||||
|
||||
function fictioneer_output_head_critical_scripts() {
|
||||
// Start HTML ---> ?>
|
||||
<script id="fictioneer-critical-scripts" data-no-optimize="1" data-no-defer="1" data-no-minify="1">!function(){if("undefined"!=typeof localStorage){const e=localStorage.getItem("fcnLightmode"),t=document.documentElement;let a,o=localStorage.getItem("fcnSiteSettings");if(o&&(o=JSON.parse(o))&&null!==o&&"object"==typeof o){Object.entries(o).forEach((([e,r])=>{switch(e){case"minimal":t.classList.toggle("minimal",r);break;case"darken":a=r>=0?1+r**2:1-r**2,t.style.setProperty("--darken",`(${a} + var(--lightness-offset))`);break;case"saturation":case"font-lightness":case"font-saturation":a=r>=0?1+r**2:1-r**2,t.style.setProperty(`--${e}`,`(${a} + var(--${e}-offset))`);break;case"hue-rotate":a=Number.isInteger(o["hue-rotate"])?o["hue-rotate"]:0,t.style.setProperty("--hue-rotate",`(${a}deg + var(--hue-offset))`);break;default:t.classList.toggle(`no-${e}`,!r)}})),t.dataset.fontWeight=o.hasOwnProperty("font-weight")?o["font-weight"]:"default",t.dataset.theme=o.hasOwnProperty("site-theme")&&!t.dataset.forceChildTheme?o["site-theme"]:"default";let e=getComputedStyle(document.documentElement).getPropertyValue("--theme-color-base").trim().split(" ");const r=o.darken?o.darken:0,s=o.saturation?o.saturation:0,n=o["hue-rotate"]?o["hue-rotate"]:0,l=r>=0?1+r**2:1-r**2;o=s>=0?1+s**2:1-s**2,e=`hsl(${(parseInt(e[0])+n)%360}deg ${(parseInt(e[1])*o).toFixed(2)}% ${(parseInt(e[2])*l).toFixed(2)}%)`,document.querySelector("meta[name=theme-color]").setAttribute("content",e)}e&&(t.dataset.mode="true"==e?"light":"dark")}}();</script>
|
||||
<script id="fictioneer-critical-scripts" data-no-optimize="1" data-no-defer="1" data-no-minify="1">!function(){if("undefined"!=typeof localStorage){const e=localStorage.getItem("fcnLightmode"),t=document.documentElement;let a,o=localStorage.getItem("fcnSiteSettings");if(o&&(o=JSON.parse(o))&&null!==o&&"object"==typeof o){Object.entries(o).forEach((([e,r])=>{switch(e){case"minimal":t.classList.toggle("minimal",r);break;case"darken":a=r>=0?1+r**2:1-r**2,t.style.setProperty("--darken",`(${a} + var(--lightness-offset))`);break;case"saturation":case"font-lightness":case"font-saturation":a=r>=0?1+r**2:1-r**2,t.style.setProperty(`--${e}`,`(${a} + var(--${e}-offset))`);break;case"hue-rotate":a=Number.isInteger(o["hue-rotate"])?o["hue-rotate"]:0,t.style.setProperty("--hue-rotate",`(${a}deg + var(--hue-offset))`);break;default:t.classList.toggle(`no-${e}`,!r)}})),t.dataset.fontWeight=o["font-weight"]?o["font-weight"]:"default",t.dataset.theme=o["site-theme"]&&!t.dataset.forceChildTheme?o["site-theme"]:"default";let e=getComputedStyle(document.documentElement).getPropertyValue("--theme-color-base").trim().split(" ");const r=o.darken?o.darken:0,s=o.saturation?o.saturation:0,n=o["hue-rotate"]?o["hue-rotate"]:0,l=r>=0?1+r**2:1-r**2;o=s>=0?1+s**2:1-s**2,e=`hsl(${(parseInt(e[0])+n)%360}deg ${(parseInt(e[1])*o).toFixed(2)}% ${(parseInt(e[2])*l).toFixed(2)}%)`,document.querySelector("meta[name=theme-color]").setAttribute("content",e)}e&&(t.dataset.mode="true"==e?"light":"dark")}}();</script>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
}
|
||||
|
@ -555,30 +555,6 @@ function fictioneer_add_content_warning_taxonomy() {
|
||||
}
|
||||
add_action( 'init', 'fictioneer_add_content_warning_taxonomy', 0 );
|
||||
|
||||
// =============================================================================
|
||||
// MANUALLY REGISTER
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Manually registers custom post types and taxonomies
|
||||
*
|
||||
* Note: This is mainly for the fast AJAX pipeline since
|
||||
* the 'init' hook will not be called.
|
||||
*
|
||||
* @since 5.9.4
|
||||
*/
|
||||
|
||||
function fictioneer_register_cpt_and_tax() {
|
||||
fictioneer_fcn_story_post_type();
|
||||
fictioneer_fcn_chapter_post_type();
|
||||
fictioneer_fcn_collection_post_type();
|
||||
fictioneer_fcn_recommendation_post_type();
|
||||
fictioneer_add_genre_taxonomy();
|
||||
fictioneer_add_fandom_taxonomy();
|
||||
fictioneer_add_character_taxonomy();
|
||||
fictioneer_add_content_warning_taxonomy();
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// MODIFY DEFAULT CATEGORIES AND POST TAGS
|
||||
// =============================================================================
|
||||
|
@ -1372,3 +1372,76 @@ function fictioneer_disable_font_library( $editor_settings ) {
|
||||
return $editor_settings;
|
||||
}
|
||||
add_filter( 'block_editor_settings_all', 'fictioneer_disable_font_library' );
|
||||
|
||||
// =============================================================================
|
||||
// FAST AJAX REQUESTS
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Accelerate AJAX requests by exiting early
|
||||
*
|
||||
* Note: Requests are validated with fictioneer_get_validated_ajax_user(),
|
||||
* making sure that AJAX functions without "_nopriv" are not executed for
|
||||
* unauthenticated users.
|
||||
*
|
||||
* @since 5.15.3
|
||||
*/
|
||||
|
||||
function fictioneer_fast_ajax() {
|
||||
$action = sanitize_key( $_REQUEST['action'] ?? '' );
|
||||
|
||||
if ( ! $action ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$functions = array(
|
||||
// Bookmarks
|
||||
'fictioneer_ajax_save_bookmarks',
|
||||
// Follows
|
||||
'fictioneer_ajax_toggle_follow',
|
||||
'fictioneer_ajax_clear_my_follows',
|
||||
'fictioneer_ajax_mark_follows_read',
|
||||
'fictioneer_ajax_get_follows_notifications',
|
||||
'fictioneer_ajax_get_follows_list',
|
||||
// Reminders
|
||||
'fictioneer_ajax_toggle_reminder',
|
||||
'fictioneer_ajax_clear_my_reminders',
|
||||
'fictioneer_ajax_get_reminders_list',
|
||||
// Checkmarks
|
||||
'fictioneer_ajax_set_checkmark',
|
||||
'fictioneer_ajax_clear_my_checkmarks',
|
||||
'fictioneer_ajax_get_finished_checkmarks_list',
|
||||
// User
|
||||
'fictioneer_ajax_get_auth',
|
||||
'fictioneer_ajax_get_user_data',
|
||||
'fictioneer_ajax_get_avatar',
|
||||
// Admin
|
||||
'fictioneer_ajax_query_relationship_posts',
|
||||
'fictioneer_ajax_search_posts_to_unlock'
|
||||
);
|
||||
|
||||
if ( get_option( 'fictioneer_enable_fast_ajax_comments' ) && isset( $_REQUEST['fcn_fast_comment_ajax'] ) ) {
|
||||
$functions = array_merge(
|
||||
$functions,
|
||||
array(
|
||||
// Comments
|
||||
'fictioneer_ajax_delete_my_comment',
|
||||
'fictioneer_ajax_moderate_comment',
|
||||
'fictioneer_ajax_report_comment',
|
||||
'fictioneer_ajax_get_comment_form',
|
||||
'fictioneer_ajax_get_comment_section',
|
||||
'fictioneer_ajax_submit_comment',
|
||||
'fictioneer_ajax_edit_comment'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( in_array( $action, $functions ) && function_exists( $action ) ) {
|
||||
call_user_func( $action );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_REQUEST['fcn_fast_ajax'] ) || isset( $_REQUEST['fcn_fast_comment_ajax'] ) ) {
|
||||
add_action( 'init', 'fictioneer_fast_ajax', 99999 );
|
||||
}
|
||||
|
@ -594,7 +594,7 @@ if ( get_option( 'fictioneer_enable_user_comment_editing' ) ) {
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_delete_my_comment() {
|
||||
// Enabled for fast AJAX?
|
||||
// Enabled?
|
||||
if ( get_option( 'fictioneer_disable_comment_callback' ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'error' => __( 'Not allowed.', 'fictioneer' ) ),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -457,18 +457,19 @@ function fictioneer_settings_capability_checkbox( $cap, $name, $set ) {
|
||||
*
|
||||
* @since 5.7.2
|
||||
*
|
||||
* @param string $option The name of the setting option.
|
||||
* @param string $sub_label Optional. The description below the label.
|
||||
* @param string $option The name of the setting option.
|
||||
* @param string $label Label of the setting.
|
||||
* @param string|null $description Optional. The description below the label.
|
||||
*/
|
||||
|
||||
function fictioneer_settings_label_checkbox( $option, $sub_label = null ) {
|
||||
function fictioneer_settings_label_checkbox( $option, $label, $description = null ) {
|
||||
// Start HTML ---> ?>
|
||||
<label class="fictioneer-label-checkbox" for="<?php echo $option; ?>">
|
||||
<input name="<?php echo $option; ?>" type="checkbox" id="<?php echo $option; ?>" <?php echo checked( 1, get_option( $option ), false ); ?> value="1" autocomplete="off">
|
||||
<div>
|
||||
<span><?php echo FICTIONEER_OPTIONS['booleans'][ $option ]['label']; ?></span>
|
||||
<?php if ( ! empty( $sub_label ) ) : ?>
|
||||
<p class="fictioneer-sub-label"><?php echo $sub_label; ?></p>
|
||||
<span><?php echo $label; ?></span>
|
||||
<?php if ( ! empty( $description ) ) : ?>
|
||||
<p class="fictioneer-sub-label"><?php echo $description; ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</label>
|
||||
@ -480,15 +481,17 @@ function fictioneer_settings_label_checkbox( $option, $sub_label = null ) {
|
||||
*
|
||||
* @since 5.7.2
|
||||
*
|
||||
* @param string $option The name of the setting option.
|
||||
* @param string $type Optional. The field type, default 'text'.
|
||||
* @param string $option The name of the setting option.
|
||||
* @param string $label Label of the setting.
|
||||
* @param string $placeholder Optional. Placeholder of the input, default empty.
|
||||
* @param string $type Optional. The field type, default 'text'.
|
||||
*/
|
||||
|
||||
function fictioneer_settings_text_input( $option, $type = 'text' ) {
|
||||
function fictioneer_settings_text_input( $option, $label, $placeholder = '', $type = 'text' ) {
|
||||
// Start HTML ---> ?>
|
||||
<label class="fictioneer-label-textfield" for="<?php echo $option; ?>">
|
||||
<input name="<?php echo $option; ?>" placeholder="<?php echo FICTIONEER_OPTIONS['strings'][ $option ]['placeholder'] ?? ''; ?>" type="<?php echo $type; ?>" id="<?php echo $option; ?>" value="<?php echo esc_attr( get_option( $option ) ); ?>" autocomplete="off">
|
||||
<p class="fictioneer-sub-label"><?php echo FICTIONEER_OPTIONS['strings'][ $option ]['label']; ?></p>
|
||||
<input name="<?php echo $option; ?>" placeholder="<?php echo $placeholder; ?>" type="<?php echo $type; ?>" id="<?php echo $option; ?>" value="<?php echo esc_attr( get_option( $option ) ); ?>" autocomplete="off">
|
||||
<p class="fictioneer-sub-label"><?php echo $label; ?></p>
|
||||
</label>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
@ -498,10 +501,12 @@ function fictioneer_settings_text_input( $option, $type = 'text' ) {
|
||||
*
|
||||
* @since 5.15.0
|
||||
*
|
||||
* @param string $option The name of the setting option.
|
||||
* @param string $option The name of the setting option.
|
||||
* @param string $label Label of the setting.
|
||||
* @param string $placeholder Optional. Placeholder of the input, default empty.
|
||||
*/
|
||||
|
||||
function fictioneer_settings_array_input( $option ) {
|
||||
function fictioneer_settings_array_input( $option, $label, $placeholder = '' ) {
|
||||
// Setup
|
||||
$value = get_option( $option, [] ) ?: [];
|
||||
$value = is_array( $value ) ? $value : [];
|
||||
@ -509,8 +514,8 @@ function fictioneer_settings_array_input( $option ) {
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<label class="fictioneer-label-textfield" for="<?php echo $option; ?>">
|
||||
<input name="<?php echo $option; ?>" placeholder="<?php echo FICTIONEER_OPTIONS['strings'][ $option ]['placeholder'] ?? ''; ?>" type="text" id="<?php echo $option; ?>" value="<?php echo esc_attr( $value ); ?>" autocomplete="off">
|
||||
<p class="fictioneer-sub-label"><?php echo FICTIONEER_OPTIONS['strings'][ $option ]['label']; ?></p>
|
||||
<input name="<?php echo $option; ?>" placeholder="<?php echo $placeholder; ?>" type="text" id="<?php echo $option; ?>" value="<?php echo esc_attr( $value ); ?>" autocomplete="off">
|
||||
<p class="fictioneer-sub-label"><?php echo $label; ?></p>
|
||||
</label>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
@ -521,13 +526,14 @@ function fictioneer_settings_array_input( $option ) {
|
||||
* @since 5.7.2
|
||||
*
|
||||
* @param string $option The name of the setting option.
|
||||
* @param string $label Label of the setting.
|
||||
* @param string $height Optional. The height with unit, default 'auto'.
|
||||
*/
|
||||
|
||||
function fictioneer_settings_textarea( $option, $height = 'auto' ) {
|
||||
function fictioneer_settings_textarea( $option, $label, $height = 'auto' ) {
|
||||
// Start HTML ---> ?>
|
||||
<textarea class="fictioneer-textarea" name="<?php echo $option; ?>" id="<?php echo $option; ?>" rows="4" style="height: <?php echo $height; ?>;"><?php echo get_option( $option ); ?></textarea>
|
||||
<p class="fictioneer-sub-label"><?php echo FICTIONEER_OPTIONS['strings'][ $option ]['label']; ?></p>
|
||||
<p class="fictioneer-sub-label"><?php echo $label; ?></p>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
|
||||
@ -537,9 +543,10 @@ function fictioneer_settings_textarea( $option, $height = 'auto' ) {
|
||||
* @since 5.7.2
|
||||
*
|
||||
* @param string $option The name of the setting option.
|
||||
* @param string $label Label of the setting.
|
||||
*/
|
||||
|
||||
function fictioneer_settings_page_assignment( $option ) {
|
||||
function fictioneer_settings_page_assignment( $option, $label ) {
|
||||
wp_dropdown_pages(
|
||||
array(
|
||||
'name' => $option,
|
||||
@ -550,5 +557,5 @@ function fictioneer_settings_page_assignment( $option ) {
|
||||
)
|
||||
);
|
||||
|
||||
echo '<p class="fictioneer-sub-label">' . FICTIONEER_OPTIONS['integers'][ $option ]['label'] . '</p>';
|
||||
echo '<p class="fictioneer-sub-label">' . $label . '</p>';
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ function fictioneer_log_post_update( $post_id, $action ) {
|
||||
|
||||
// Build message
|
||||
$message = sprintf(
|
||||
_x( '%1$s #%2$s %3$s: %4$s', 'Pattern for post/page in logs: "{Type} #{ID} {Action}: {Title}".', 'fictioneer' ),
|
||||
_x( '%1$s #%2$s %3$s: %4$s', 'Pattern for post/page in logs: {Type} #{ID} {Action}: {Title}.', 'fictioneer' ),
|
||||
$post_type_name,
|
||||
$post_id,
|
||||
$action,
|
||||
@ -146,7 +146,7 @@ function fictioneer_log_checkbox_update( $option, $old_value, $value ) {
|
||||
|
||||
// Build message
|
||||
$update = sprintf(
|
||||
_x( '%1$s: %2$s', 'Pattern for checkbox option in logs: "{Checked} {Option}".', 'fictioneer' ),
|
||||
_x( '%1$s: %2$s', 'Pattern for checkbox option in logs.', 'fictioneer' ),
|
||||
$value ? _x( 'Checked', 'State of checkbox option in logs.', 'fictioneer' ) : _x( 'Unchecked', 'State of checkbox option in logs.', 'fictioneer' ),
|
||||
$option
|
||||
);
|
||||
@ -172,7 +172,7 @@ function fictioneer_settings_checkbox_added( $option, $value ) {
|
||||
|
||||
// Relay
|
||||
fictioneer_log_checkbox_update(
|
||||
FICTIONEER_OPTIONS['booleans'][ $option ]['label'],
|
||||
fictioneer_get_option_label( $option ),
|
||||
null,
|
||||
$value
|
||||
);
|
||||
@ -197,7 +197,7 @@ function fictioneer_settings_checkbox_updated( $option, $old_value, $value ) {
|
||||
|
||||
// Relay
|
||||
fictioneer_log_checkbox_update(
|
||||
FICTIONEER_OPTIONS['booleans'][ $option ]['label'],
|
||||
fictioneer_get_option_label( $option ),
|
||||
$old_value,
|
||||
$value
|
||||
);
|
||||
@ -216,6 +216,7 @@ define(
|
||||
'fictioneer_stories_page',
|
||||
'fictioneer_chapters_page',
|
||||
'fictioneer_recommendations_page',
|
||||
'fictioneer_collections_page',
|
||||
'fictioneer_bookshelf_page',
|
||||
'fictioneer_404_page'
|
||||
)
|
||||
@ -240,8 +241,8 @@ function fictioneer_log_page_assignment_update( $option, $old_value, $value ) {
|
||||
// Build message
|
||||
$message = sprintf(
|
||||
_x(
|
||||
'%1$s page assignment changed from #%2$s to #%3$s',
|
||||
'Pattern for page assignment updates in logs: "{Option} page assignment changed from {Old ID} to {New ID}.".',
|
||||
'%1$s changed from "%2$s" to "%3$s"',
|
||||
'Pattern for page assignment updates in logs.',
|
||||
'fictioneer'
|
||||
),
|
||||
$option,
|
||||
@ -270,7 +271,7 @@ function fictioneer_settings_page_assignment_added( $option, $value ) {
|
||||
|
||||
// Relay
|
||||
fictioneer_log_page_assignment_update(
|
||||
FICTIONEER_OPTIONS['integers'][ $option ]['label'],
|
||||
fictioneer_get_option_label( $option ),
|
||||
null,
|
||||
$value
|
||||
);
|
||||
@ -295,7 +296,7 @@ function fictioneer_settings_page_assignment_updated( $option, $old_value, $valu
|
||||
|
||||
// Relay
|
||||
fictioneer_log_page_assignment_update(
|
||||
FICTIONEER_OPTIONS['integers'][ $option ]['label'],
|
||||
fictioneer_get_option_label( $option ),
|
||||
$old_value,
|
||||
$value
|
||||
);
|
||||
@ -312,7 +313,9 @@ define(
|
||||
'fictioneer_phrase_maintenance',
|
||||
'fictioneer_phrase_login_modal',
|
||||
'fictioneer_phrase_cookie_consent_banner',
|
||||
'fictioneer_phrase_comment_reply_notification'
|
||||
'fictioneer_phrase_comment_reply_notification',
|
||||
'fictioneer_phrase_site_age_confirmation',
|
||||
'fictioneer_phrase_post_age_confirmation'
|
||||
)
|
||||
);
|
||||
|
||||
@ -335,8 +338,8 @@ function fictioneer_log_phrase_update( $option, $old_value, $value ) {
|
||||
// Build message
|
||||
$message = sprintf(
|
||||
_x(
|
||||
'Phrase for the %1$s changed to \'%2$s\'',
|
||||
'Pattern for phrase updates in logs: "Phrase for the {Option} changed to: \'{New String}\'".',
|
||||
'%1$s phrase changed to "%2$s"',
|
||||
'Pattern for phrase updates in logs.',
|
||||
'fictioneer'
|
||||
),
|
||||
$option,
|
||||
@ -364,7 +367,7 @@ function fictioneer_settings_phrase_added( $option, $value ) {
|
||||
|
||||
// Relay
|
||||
fictioneer_log_phrase_update(
|
||||
FICTIONEER_OPTIONS['strings'][ $option ]['label'],
|
||||
fictioneer_get_option_label( $option ),
|
||||
null,
|
||||
$value
|
||||
);
|
||||
@ -389,7 +392,7 @@ function fictioneer_settings_phrase_updated( $option, $old_value, $value ) {
|
||||
|
||||
// Replay
|
||||
fictioneer_log_phrase_update(
|
||||
FICTIONEER_OPTIONS['strings'][ $option ]['label'],
|
||||
fictioneer_get_option_label( $option ),
|
||||
$old_value,
|
||||
$value
|
||||
);
|
||||
@ -414,7 +417,8 @@ define(
|
||||
'fictioneer_patreon_client_id',
|
||||
'fictioneer_patreon_client_secret',
|
||||
'fictioneer_patreon_global_lock_tiers',
|
||||
'fictioneer_patreon_global_lock_amount'
|
||||
'fictioneer_patreon_global_lock_amount',
|
||||
'fictioneer_patreon_global_lock_unlock_amount'
|
||||
)
|
||||
);
|
||||
|
||||
@ -438,7 +442,7 @@ function fictioneer_log_connection_update( $connection, $old_value, $value ) {
|
||||
$message = sprintf(
|
||||
_x(
|
||||
'%s updated.',
|
||||
'Pattern for connection updates in logs: "{Option} updated".',
|
||||
'Pattern for connection updates in logs.',
|
||||
'fictioneer'
|
||||
),
|
||||
$connection
|
||||
@ -465,7 +469,7 @@ function fictioneer_settings_connection_added( $option, $value ) {
|
||||
|
||||
// Relay
|
||||
fictioneer_log_connection_update(
|
||||
FICTIONEER_OPTIONS['strings'][ $option ]['label'],
|
||||
fictioneer_get_option_label( $option ),
|
||||
null,
|
||||
$value
|
||||
);
|
||||
@ -490,7 +494,7 @@ function fictioneer_settings_connection_updated( $option, $old_value, $value ) {
|
||||
|
||||
// Relay
|
||||
fictioneer_log_connection_update(
|
||||
FICTIONEER_OPTIONS['strings'][ $option ]['label'],
|
||||
fictioneer_get_option_label( $option ),
|
||||
$old_value,
|
||||
$value
|
||||
);
|
||||
|
@ -30,15 +30,30 @@ $patreon_tiers = is_array( $patreon_tiers ) ? $patreon_tiers : [];
|
||||
<div class="fictioneer-card__content">
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_discord_client_id' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_discord_client_id',
|
||||
__( 'Discord Client ID', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_discord_client_secret' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_discord_client_secret',
|
||||
__( 'Discord Client Secret', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_discord_invite_link' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_discord_invite_link',
|
||||
__( 'Discord invite link', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
@ -48,15 +63,30 @@ $patreon_tiers = is_array( $patreon_tiers ) ? $patreon_tiers : [];
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_discord_channel_comments_webhook' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_discord_channel_comments_webhook',
|
||||
__( 'Discord comment channel webhook • Shows excerpts of (private) comments!', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_discord_channel_stories_webhook' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_discord_channel_stories_webhook',
|
||||
__( 'Discord story channel webhook', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_discord_channel_chapters_webhook' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_discord_channel_chapters_webhook',
|
||||
__( 'Discord chapter channel webhook', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -69,11 +99,21 @@ $patreon_tiers = is_array( $patreon_tiers ) ? $patreon_tiers : [];
|
||||
<div class="fictioneer-card__content">
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_twitch_client_id' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_twitch_client_id',
|
||||
__( 'Twitch Client ID', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_twitch_client_secret' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_twitch_client_secret',
|
||||
__( 'Twitch Client Secret', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -86,11 +126,21 @@ $patreon_tiers = is_array( $patreon_tiers ) ? $patreon_tiers : [];
|
||||
<div class="fictioneer-card__content">
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_google_client_id' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_google_client_id',
|
||||
__( 'Google Client ID', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_google_client_secret' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_google_client_secret',
|
||||
__( 'Google Client Secret', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -103,19 +153,39 @@ $patreon_tiers = is_array( $patreon_tiers ) ? $patreon_tiers : [];
|
||||
<div class="fictioneer-card__content">
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_patreon_client_id' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_patreon_client_id',
|
||||
__( 'Patreon Client ID', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_patreon_client_secret' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_patreon_client_secret',
|
||||
__( 'Patreon Client Secret', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_patreon_campaign_link' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_patreon_campaign_link',
|
||||
__( 'Patreon campaign link', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_patreon_unlock_message' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_patreon_unlock_message',
|
||||
__( 'Patreon gate message override (leave empty for default)', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
@ -125,19 +195,48 @@ $patreon_tiers = is_array( $patreon_tiers ) ? $patreon_tiers : [];
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_array_input( 'fictioneer_patreon_global_lock_tiers' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_array_input(
|
||||
'fictioneer_patreon_global_lock_tiers',
|
||||
__( 'Global tiers to unlock posts (comma-separated list of tier IDs)', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_patreon_global_lock_amount' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_patreon_global_lock_amount',
|
||||
__( 'Global pledge threshold in cents to unlock posts (leave empty to disable)', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_patreon_global_lock_lifetime_amount' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_patreon_global_lock_lifetime_amount',
|
||||
__( 'Global lifetime pledge threshold in cents to unlock posts (leave empty to disable)', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_hide_password_form_with_patreon' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_patreon_global_lock_unlock_amount',
|
||||
__( 'Global pledge threshold in cents to gate regular post unlocks (leave empty to disable)', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_password_form_with_patreon',
|
||||
__( 'Hide password form on Patreon-gated posts', 'fictioneer' ),
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row fictioneer-card__row--buttons">
|
||||
|
@ -43,7 +43,7 @@ $disabled_fonts = is_array( $disabled_fonts ) ? $disabled_fonts : [];
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<textarea name="fictioneer_google_fonts_links" id="fictioneer_google_fonts_links" rows="4" placeholder="<?php echo FICTIONEER_OPTIONS['strings']['fictioneer_google_fonts_links']['placeholder'] ?? ''; ?>"><?php echo get_option( 'fictioneer_google_fonts_links' ); ?></textarea>
|
||||
<textarea name="fictioneer_google_fonts_links" id="fictioneer_google_fonts_links" rows="4" placeholder="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap"><?php echo get_option( 'fictioneer_google_fonts_links' ); ?></textarea>
|
||||
<p class="fictioneer-sub-label"><?php _e( 'Only one font per link per line.', 'fictioneer' ); ?></p>
|
||||
</div>
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_maintenance_mode',
|
||||
__( 'Enable maintenance mode', 'fictioneer' ),
|
||||
__( 'Locks down the site with a maintenance notice.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -57,6 +58,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_dark_mode_as_default',
|
||||
__( 'Enable dark mode as default', 'fictioneer' ),
|
||||
__( 'Overridden by personal site settings.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -66,6 +68,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_show_authors',
|
||||
__( 'Display authors on cards and posts', 'fictioneer' ),
|
||||
__( 'When you have multiple publishing authors.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -75,6 +78,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_show_full_post_content',
|
||||
__( 'Display full posts instead of excerpts', 'fictioneer' ),
|
||||
__( 'You can still use the [More] block for shortened previews.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -84,6 +88,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_site_age_confirmation',
|
||||
__( 'Enable age confirmation modal for site', 'fictioneer' ),
|
||||
__( 'Require age confirmation for the whole site.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -93,6 +98,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_contact_forms',
|
||||
__( 'Disable theme contact forms', 'fictioneer' ),
|
||||
__( 'Emergency stop with an error notice.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -126,15 +132,34 @@
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_system_email_address', 'email' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_system_email_address',
|
||||
__( 'System email address', 'fictioneer' ),
|
||||
'noreply@example.com',
|
||||
'email'
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_system_email_name' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_system_email_name',
|
||||
__( 'System email name', 'fictioneer' ),
|
||||
get_bloginfo( 'name' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_textarea( 'fictioneer_contact_email_addresses', '205px' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_textarea(
|
||||
'fictioneer_contact_email_addresses',
|
||||
__( 'Contact form receivers (one email address per line)', 'fictioneer' ),
|
||||
'205px'
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -154,6 +179,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_post_age_confirmation',
|
||||
__( 'Enable age confirmation modal for posts', 'fictioneer' ),
|
||||
__( 'Require age confirmation for <b>adult-rated</b> content.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -163,6 +189,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_show_protected_excerpt',
|
||||
__( 'Show excerpt on password-protected posts', 'fictioneer' ),
|
||||
__( 'This may be beneficial for search engines.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -172,6 +199,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_chapter_icons',
|
||||
__( 'Hide chapter icons', 'fictioneer' ),
|
||||
__( 'Hides the icons on story pages and in the mobile menu.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -181,6 +209,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_chapter_groups',
|
||||
__( 'Enable chapter groups', 'fictioneer' ),
|
||||
__( 'Display chapters in groups on story pages (if set).', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -190,6 +219,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_collapse_groups_by_default',
|
||||
__( 'Collapse chapter groups by default', 'fictioneer' ),
|
||||
__( 'Chapter groups (if used) are collapsed on page load.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -199,6 +229,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_chapter_collapsing',
|
||||
__( 'Disable collapsing of chapters', 'fictioneer' ),
|
||||
__( 'Do not collapse long chapter lists.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -208,6 +239,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_chapter_appending',
|
||||
__( 'Append new chapters to story', 'fictioneer' ),
|
||||
__( 'Only once when the chapter is first saved.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -217,6 +249,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_limit_chapter_stories_by_author',
|
||||
__( 'Restrict chapter stories by author', 'fictioneer' ),
|
||||
__( 'Also disables cross-posting as guest author.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -234,6 +267,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_show_story_changelog',
|
||||
__( 'Show story changelog button', 'fictioneer' ),
|
||||
__( 'Opens modal with timestamped chapter changes.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -243,6 +277,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_large_card_chapter_list',
|
||||
__( 'Hide latest chapter list on large story cards', 'fictioneer' ),
|
||||
__( 'Less informative but also less cluttered.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -252,6 +287,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_count_characters_as_words',
|
||||
__( 'Count characters instead of words', 'fictioneer' ),
|
||||
__( 'For logographic writing systems. Use the word count multiplier to better approximate the number.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -289,19 +325,39 @@
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_hide_taxonomies_on_story_cards' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_taxonomies_on_story_cards',
|
||||
__( 'Hide taxonomies on story cards', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_hide_taxonomies_on_chapter_cards' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_taxonomies_on_chapter_cards',
|
||||
__( 'Hide taxonomies on chapter cards', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_hide_taxonomies_on_recommendation_cards' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_taxonomies_on_recommendation_cards',
|
||||
__( 'Hide taxonomies on recommendation cards', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_hide_taxonomies_on_collection_cards' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_taxonomies_on_collection_cards',
|
||||
__( 'Hide taxonomies on collection cards', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
@ -309,19 +365,39 @@
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_show_tags_on_story_cards' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_show_tags_on_story_cards',
|
||||
__( 'Show tags on story cards', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_show_tags_on_chapter_cards' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_show_tags_on_chapter_cards',
|
||||
__( 'Show tags on chapter cards', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_show_tags_on_recommendation_cards' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_show_tags_on_recommendation_cards',
|
||||
__( 'Show tags on recommendation cards', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_show_tags_on_collection_cards' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_show_tags_on_collection_cards',
|
||||
__( 'Show tags on collection cards', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
@ -329,15 +405,30 @@
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_hide_taxonomies_on_pages' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_taxonomies_on_pages',
|
||||
__( 'Hide taxonomies on pages', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_hide_tags_on_pages' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_tags_on_pages',
|
||||
__( 'Hide tags on pages', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_hide_content_warnings_on_pages' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_hide_content_warnings_on_pages',
|
||||
__( 'Hide content warnings on pages', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -354,35 +445,75 @@
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_page_assignment( 'fictioneer_user_profile_page' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_page_assignment(
|
||||
'fictioneer_user_profile_page',
|
||||
__( 'Account page (Template: User Profile) • Do not cache!', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_page_assignment( 'fictioneer_bookmarks_page' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_page_assignment(
|
||||
'fictioneer_bookmarks_page',
|
||||
__( 'Bookmarks page (Template: Bookmarks)', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_page_assignment( 'fictioneer_stories_page' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_page_assignment(
|
||||
'fictioneer_stories_page',
|
||||
__( 'Stories page (Template: Stories)', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_page_assignment( 'fictioneer_chapters_page' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_page_assignment(
|
||||
'fictioneer_chapters_page',
|
||||
__( 'Chapters page (Template: Chapters)', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_page_assignment( 'fictioneer_recommendations_page' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_page_assignment(
|
||||
'fictioneer_recommendations_page',
|
||||
__( 'Recommendations page (Template: Recommendations)', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_page_assignment( 'fictioneer_collections_page' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_page_assignment(
|
||||
'fictioneer_collections_page',
|
||||
__( 'Collections page (Template: Collections)', 'fictioneer' ),
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_page_assignment( 'fictioneer_bookshelf_page' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_page_assignment(
|
||||
'fictioneer_bookshelf_page',
|
||||
__( 'Bookshelf page (Template: Bookshelf) • Do not cache!', 'fictioneer' ),
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_page_assignment( 'fictioneer_404_page' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_page_assignment(
|
||||
'fictioneer_404_page',
|
||||
__( '404 page • Add content to your 404 page, make it useful!', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
@ -402,6 +533,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_storygraph_api',
|
||||
__( 'Enable Storygraph API', 'fictioneer' ),
|
||||
__( 'Reach a larger audience by allowing external services to index and search your stories (meta data only).', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -411,6 +543,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_oauth',
|
||||
__( 'Enable OAuth 2.0 authentication', 'fictioneer' ),
|
||||
sprintf(
|
||||
__( 'Register/Login with social media accounts. This requires you to <a href="%s" target="_blank">set up an application</a> for each service provider.', 'fictioneer' ),
|
||||
'https://github.com/Tetrakern/fictioneer/blob/main/DOCUMENTATION.md#users--oauth'
|
||||
@ -423,6 +556,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_patreon_locks',
|
||||
__( 'Enable Patreon content gate', 'fictioneer' ),
|
||||
__( 'Requires OAuth 2.0 application for Patreon. Allows eligible logged-in members to ignore post passwords.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -432,6 +566,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_lightbox',
|
||||
__( 'Enable lightbox', 'fictioneer' ),
|
||||
__( 'Enlarge images in floating container on click.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -441,6 +576,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_bookmarks',
|
||||
__( 'Enable Bookmarks', 'fictioneer' ),
|
||||
__( 'Bookmark paragraphs in chapters. No account needed.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -450,6 +586,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_follows',
|
||||
__( 'Enable Follows (requires account)', 'fictioneer' ),
|
||||
__( 'Follow stories and get on-site alerts for updates.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -459,6 +596,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_checkmarks',
|
||||
__( 'Enable Checkmarks (requires account)', 'fictioneer' ),
|
||||
__( 'Mark chapters and stories as "read".', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -468,6 +606,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_reminders',
|
||||
__( 'Enable Reminders (requires account)', 'fictioneer' ),
|
||||
__( 'Remember stories to be "read later".', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -477,6 +616,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_suggestions',
|
||||
__( 'Enable Suggestions', 'fictioneer' ),
|
||||
__( 'Suggest color-coded text changes in the comments.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -486,6 +626,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_theme_rss',
|
||||
__( 'Enable theme RSS feeds and buttons', 'fictioneer' ),
|
||||
__( 'Replace the default WordPress RSS feeds with theme feeds built for publishing your stories and chapters.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -495,6 +636,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_seo',
|
||||
__( 'Enable SEO features', 'fictioneer' ),
|
||||
__( 'Open Graph images, chat embeds, meta tags, and schema graphs for rich snippets. Incompatible with SEO plugins.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -504,6 +646,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_sitemap',
|
||||
__( 'Enable theme sitemap generation', 'fictioneer' ),
|
||||
__( 'Customized sitemap for search engines to crawl. Respects unlisted flags and custom post types. Can be slow.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -513,6 +656,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_tts',
|
||||
__( 'Enable Text-To-Speech (experimental)', 'fictioneer' ),
|
||||
__( 'Sometimes wonky browser-based text-to-speech engine. Extend and availability depends on the browser and OS.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -522,6 +666,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_epubs',
|
||||
__( 'Enable ePUB converter (experimental)', 'fictioneer' ),
|
||||
__( 'Automatically generated ePUBs. Can take a while and may fail due to non-conform content or excessive size. You can alternatively upload manually created ebooks as well.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -541,13 +686,20 @@
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_comment_form_selector' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_comment_form_selector',
|
||||
__( 'CSS selector for the comment form. Attempts to make scripts work with comment plugin. Clear theme cache after updating.', 'fictioneer' ),
|
||||
'#comment'
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_commenting',
|
||||
__( 'Disable commenting across the site', 'fictioneer' ),
|
||||
__( 'Still shows the current comments.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -557,6 +709,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_require_js_to_comment',
|
||||
__( 'Require JavaScript to comment', 'fictioneer' ),
|
||||
__( 'Simple but effective spam protection.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -581,6 +734,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_ajax_comment_submit',
|
||||
__( 'Enable AJAX comment submission', 'fictioneer' ),
|
||||
__( 'Does not reload the page on submit.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -590,6 +744,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_ajax_comment_moderation',
|
||||
__( 'Enable AJAX comment moderation', 'fictioneer' ),
|
||||
__( 'Moderation actions directly in the comment section.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -599,9 +754,10 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_fast_ajax_comments',
|
||||
__( 'Enable fast AJAX for comments', 'fictioneer' ),
|
||||
sprintf(
|
||||
__( 'Accelerate AJAX comment requests by skipping plugins and theme initialization. Actions and filters will be ignored unless applied by core or a <a href="%s" target="_blank">must-use plugin</a>.', 'fictioneer' ),
|
||||
'https://wordpress.org/documentation/article/must-use-plugins/'
|
||||
__( 'Accelerate comments by skipping most plugins. Requires the <a href="%s" target="_blank">Fast Requests</a> mu-plugin to be installed.', 'fictioneer' ),
|
||||
'https://github.com/Tetrakern/fictioneer/blob/main/INSTALLATION.md#recommended-must-use-plugins'
|
||||
)
|
||||
);
|
||||
?>
|
||||
@ -611,6 +767,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_comment_toolbar',
|
||||
__( 'Enable comment toolbar', 'fictioneer' ),
|
||||
__( 'Quick buttons to wrap text selection in BBCodes.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -620,6 +777,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_custom_badges',
|
||||
__( 'Enable custom badges', 'fictioneer' ),
|
||||
__( 'Assign custom badges (but users can disable them).', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -629,6 +787,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_patreon_badges',
|
||||
__( 'Enable Patreon badges', 'fictioneer' ),
|
||||
sprintf(
|
||||
__( 'Show supporter badge for the <a href="%s">linked Patreon client</a>. This only works for the owner of the linked client. You cannot add campaigns for individual authors.', 'fictioneer' ),
|
||||
'?page=fictioneer_connections'
|
||||
@ -638,13 +797,20 @@
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row fictioneer-card__row--checkbox-inset">
|
||||
<?php fictioneer_settings_text_input( 'fictioneer_patreon_label' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_text_input(
|
||||
'fictioneer_patreon_label',
|
||||
__( 'Patreon badge label', 'fictioneer' ),
|
||||
_x( 'Patron', 'Default Patreon supporter badge label.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_comment_notifications',
|
||||
__( 'Enable comment reply notifications', 'fictioneer' ),
|
||||
__( 'Notify commenters about replies via email (if provided).', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -654,6 +820,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_sticky_comments',
|
||||
__( 'Enable sticky comments', 'fictioneer' ),
|
||||
__( 'Always on top of the first page.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -663,6 +830,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_private_commenting',
|
||||
__( 'Enable private commenting', 'fictioneer' ),
|
||||
__( 'Private comments are invisible to the public.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -672,6 +840,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_comment_reporting',
|
||||
__( 'Enable comment reporting', 'fictioneer' ),
|
||||
__( 'Logged-in users can report comments via flag button.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -702,7 +871,13 @@
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_textarea( 'fictioneer_comments_notice', '214px' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_textarea(
|
||||
'fictioneer_comments_notice',
|
||||
__( 'Notice above comments. Leave empty to hide. HTML allowed.', 'fictioneer' ),
|
||||
'214px'
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -718,6 +893,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_heartbeat',
|
||||
__( 'Disable Heartbeat API', 'fictioneer' ),
|
||||
__( 'No more continuous requests for near real-time updates and autosaves, which can strain the server.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -727,6 +903,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_remove_head_clutter',
|
||||
__( 'Remove clutter from HTML head', 'fictioneer' ),
|
||||
__( 'Less meta tags, scripts, and styles in the <head>.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -736,6 +913,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_remove_wp_svg_filters',
|
||||
__( 'Remove global WordPress SVG filters', 'fictioneer' ),
|
||||
__( 'If not used, these are just clutter in the <body>. This will prevent duotone filters from working.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -745,6 +923,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_reduce_admin_bar',
|
||||
__( 'Reduce admin bar items', 'fictioneer' ),
|
||||
__( 'Less menu items, links, and icons in the admin bar.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -754,6 +933,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_all_widgets',
|
||||
__( 'Disable all widgets', 'fictioneer' ),
|
||||
__( 'The theme does not use widgets by default and removing them slightly boosts performance.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -763,6 +943,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_bundle_stylesheets',
|
||||
__( 'Bundle CSS files into one', 'fictioneer' ),
|
||||
__( 'Faster if HTTP/2 (+) is not available to load multiple smaller files in parallel, but increases the initial payload.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -772,6 +953,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_bundle_scripts',
|
||||
__( 'Bundle JavaScript files into one', 'fictioneer' ),
|
||||
__( 'Deferred script file that should be ignored by aggregation plugins to avoid errors (fictioneer/js/complete.min.js and fictioneer/cache/dynamic-scripts.js).', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -781,6 +963,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_extended_story_list_meta_queries',
|
||||
__( 'Disable extended story list meta queries', 'fictioneer' ),
|
||||
__( 'Faster, but adds one row per story to your database, which can slow down your site if you have thousands.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -790,6 +973,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_extended_chapter_list_meta_queries',
|
||||
__( 'Disable extended chapter list meta queries', 'fictioneer' ),
|
||||
__( 'Faster, but adds one row per chapter to your database, which can slow down your site if you have thousands.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -808,6 +992,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_do_not_save_comment_ip',
|
||||
__( 'Do not save comment IP addresses', 'fictioneer' ),
|
||||
__( 'IP addresses are personal data.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -817,6 +1002,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_restrict_rest_api',
|
||||
__( 'Restrict default REST API', 'fictioneer' ),
|
||||
__( 'Disables API for guests and low-permission users.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -826,6 +1012,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_rate_limits',
|
||||
__( 'Enable rate limiting for AJAX requests', 'fictioneer' ),
|
||||
sprintf(
|
||||
__( 'Simple session-based rate limiting, allowing %s requests per minute for selected actions (per action).', 'fictioneer' ),
|
||||
FICTIONEER_REQUESTS_PER_MINUTE
|
||||
@ -838,6 +1025,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_application_passwords',
|
||||
__( 'Disable application passwords', 'fictioneer' ),
|
||||
__( 'If you do not need them, you should disable them.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -847,6 +1035,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_logout_redirects_home',
|
||||
__( 'Logout redirects Home', 'fictioneer' ),
|
||||
__( 'Prevents users from ending up on the login page.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -856,6 +1045,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_consent_wrappers',
|
||||
__( 'Add consent wrappers to embedded content', 'fictioneer' ),
|
||||
__( 'External content not loaded until deliberately clicked.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -865,6 +1055,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_see_some_evil',
|
||||
__( 'Monitor posts for suspicious content', 'fictioneer' ),
|
||||
__( 'Sends an admin email if suspicious strings are found, which could be an attempted attack or <strong>false positive.</strong>', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -874,6 +1065,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_cookie_banner',
|
||||
__( 'Enable cookie banner and consent function', 'fictioneer' ),
|
||||
__( 'Shows a generic cookie consent banner and activates the <code>fictioneer_get_consent()</code> theme function that returns either false, "necessary", or "full".', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -891,7 +1083,7 @@
|
||||
<div class="fictioneer-card__row fictioneer-card__row--inline-input">
|
||||
<p class="fictioneer-inline-text-input"><?php
|
||||
printf(
|
||||
FICTIONEER_OPTIONS['integers']['fictioneer_upload_size_limit']['label'],
|
||||
__( '<span>Limit file uploads to</span> %s <span>MB or less for user roles with the "Upload Limit" restriction.</span>', 'fictioneer' ),
|
||||
'<input name="fictioneer_upload_size_limit" type="text" id="fictioneer_upload_size_limit" value="' . esc_attr( get_option( 'fictioneer_upload_size_limit', 5 ) ?: 5 ) . '" style="font-family: Consolas, Monaco, monospace; font-size: 87.5%; text-align: center;" size="5" placeholder="5">'
|
||||
);
|
||||
?></p>
|
||||
@ -904,7 +1096,7 @@
|
||||
?>
|
||||
<textarea class="fictioneer-textarea" name="fictioneer_upload_mime_types" id="fictioneer_upload_mime_types" rows="4" style="height: 100px;" placeholder="<?php echo FICTIONEER_DEFAULT_UPLOAD_MIME_TYPE_RESTRICTIONS; ?>"><?php echo $mime_types; ?></textarea>
|
||||
<p class="fictioneer-sub-label"><?php printf(
|
||||
FICTIONEER_OPTIONS['strings']['fictioneer_upload_mime_types']['label'],
|
||||
__( 'Comma-separated list of allowed <a href="%s" target="_blank" rel="noreferrer">mime types</a> for user roles with the "Upload Restriction". Must be among the allowed mime type and file extensions of WordPress.', 'fictioneer' ),
|
||||
'https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types'
|
||||
); ?></p>
|
||||
</div>
|
||||
@ -922,6 +1114,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_properties',
|
||||
__( 'Disable Fictioneer CSS properties', 'fictioneer' ),
|
||||
__( 'Only do this if you define everything yourself.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -931,6 +1124,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_font_awesome',
|
||||
__( 'Disable Font Awesome integration', 'fictioneer' ),
|
||||
__( 'Only do this if you integrate it yourself.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -940,6 +1134,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_jquery_migrate',
|
||||
__( 'Enable jQuery migrate script', 'fictioneer' ),
|
||||
__( 'Some older plugins might require this.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -949,6 +1144,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_purge_all_caches',
|
||||
__( 'Purge all caches on content updates', 'fictioneer' ),
|
||||
__( 'Inefficient but makes sure everything is up-to-date.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -958,6 +1154,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_cache_compatibility',
|
||||
__( 'Enable cache compatibility mode', 'fictioneer' ),
|
||||
__( 'Make the theme aware of unknown caching plugins.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -967,6 +1164,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_public_cache_compatibility',
|
||||
__( 'Enable public cache compatibility mode', 'fictioneer' ),
|
||||
__( 'For serving public caches to logged-in users. Exceptions for administrators and moderators are recommended.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -976,6 +1174,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_private_cache_compatibility',
|
||||
__( 'Enable private cache compatibility mode', 'fictioneer' ),
|
||||
__( 'For serving private caches to logged-in users. Also useful if you do not serve caches to logged-in users at all.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -985,6 +1184,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_all_blocks',
|
||||
__( 'Enable all Gutenberg blocks', 'fictioneer' ),
|
||||
__( 'No guarantee these blocks work with the theme.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -994,6 +1194,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_advanced_meta_fields',
|
||||
__( 'Enable advanced meta fields', 'fictioneer' ),
|
||||
__( 'Additional options you most likely do not need.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1003,6 +1204,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_theme_logout',
|
||||
__( 'Disable theme logout without nonce', 'fictioneer' ),
|
||||
__( 'Return to the default WordPress logout with nonce.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1012,6 +1214,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_ajax_comment_form',
|
||||
__( 'Enable AJAX comment form', 'fictioneer' ),
|
||||
__( 'Load the comment form via AJAX to circumvent caching.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1021,6 +1224,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_ajax_comments',
|
||||
__( 'Enable AJAX comment section', 'fictioneer' ),
|
||||
__( 'Load the comment section and form via AJAX. More server work but circumvents caching.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1030,6 +1234,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_enable_ajax_authentication',
|
||||
__( 'Enable AJAX user authentication', 'fictioneer' ),
|
||||
__( 'Check for user login state after the page has been loaded to get around anonymizing caching strategies.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1039,6 +1244,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_theme_search',
|
||||
__( 'Disable advanced search', 'fictioneer' ),
|
||||
__( 'Return to the default search query and form.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1048,6 +1254,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_comment_bbcodes',
|
||||
__( 'Disable comment BBCodes', 'fictioneer' ),
|
||||
__( 'This will disable the comment toolbar as well.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1057,6 +1264,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_comment_callback',
|
||||
__( 'Disable theme comment style (callback)', 'fictioneer' ),
|
||||
__( 'Return to the default WordPress markup.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1066,6 +1274,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_comment_query',
|
||||
__( 'Disable theme comment query', 'fictioneer' ),
|
||||
__( 'Return to the default WordPress query.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1075,6 +1284,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_comment_form',
|
||||
__( 'Disable theme comment form', 'fictioneer' ),
|
||||
__( 'Return to the default WordPress form.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1084,6 +1294,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_comment_pagination',
|
||||
__( 'Disable theme comment pagination', 'fictioneer' ),
|
||||
__( 'Return to the default WordPress pagination (no-AJAX).', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
@ -1099,31 +1310,66 @@
|
||||
<div class="fictioneer-card__content">
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_disable_facebook_share' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_facebook_share',
|
||||
__( 'Disable Facebook share button', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_disable_twitter_share' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_twitter_share',
|
||||
__( 'Disable Twitter share button', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_disable_tumblr_share' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_tumblr_share',
|
||||
__( 'Disable Tumblr share button', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_disable_reddit_share' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_reddit_share',
|
||||
__( 'Disable Reddit share button', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_disable_mastodon_share' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_mastodon_share',
|
||||
__( 'Disable Mastodon share button', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_disable_telegram_share' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_telegram_share',
|
||||
__( 'Disable Telegram share button', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<?php fictioneer_settings_label_checkbox( 'fictioneer_disable_whatsapp_share' ); ?>
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_disable_whatsapp_share',
|
||||
__( 'Disable Whatsapp share button', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -1141,6 +1387,7 @@
|
||||
<?php
|
||||
fictioneer_settings_label_checkbox(
|
||||
'fictioneer_delete_theme_options_on_deactivation',
|
||||
__( 'Delete all settings and theme mods on deactivation', 'fictioneer' ),
|
||||
__( 'This will also remove all theme-related comment and user meta data, such as bookmarks or follows. Stories, chapters, collections, and recommendations remain, but you will need to register their custom post types to access them.', 'fictioneer' )
|
||||
);
|
||||
?>
|
||||
|
@ -51,7 +51,7 @@
|
||||
?>
|
||||
|
||||
<div class="fictioneer-card__row">
|
||||
<textarea name="fictioneer_phrase_comment_reply_notification" id="fictioneer_phrase_comment_reply_notification" rows="8" placeholder="<?php echo $default; ?>"><?php echo esc_attr( get_option( 'fictioneer_phrase_comment_reply_notification' ) ); ?></textarea>
|
||||
<textarea class="fictioneer-textarea" name="fictioneer_phrase_comment_reply_notification" rows="8" placeholder="<?php echo $default; ?>"><?php echo esc_attr( get_option( 'fictioneer_phrase_comment_reply_notification' ) ); ?></textarea>
|
||||
<p class="fictioneer-sub-label"><?php _e( 'HTML allowed, but note that many email clients do not support modern markup or styles. Better stick to 10+ years old HTML and very simple inline CSS. Also always include an unsubscribe link. <code>[[post_title]]</code> <code>[[post_url]]</code> <code>[[comment_id]]</code> <code>[[comment_name]]</code> <code>[[comment_excerpt]]</code> <code>[[reply_id]]</code> <code>[[reply_name]]</code> <code>[[reply_date]]</code> <code>[[reply_excerpt]]</code> <code>[[reply_content]]</code> <code>[[site_title]]</code> <code>[[site_url]]</code> <code>[[unsubscribe_url]]</code>', 'fictioneer' ); ?></p>
|
||||
</div>
|
||||
|
||||
|
@ -73,6 +73,7 @@ $admin_caps = array(
|
||||
'create_users',
|
||||
'edit_users',
|
||||
'remove_users',
|
||||
'fcn_unlock_posts',
|
||||
'switch_themes',
|
||||
'edit_theme_options',
|
||||
'edit_themes',
|
||||
|
@ -732,6 +732,140 @@ function fictioneer_admin_profile_fields_data_nodes( $profile_user ) {
|
||||
}
|
||||
add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_fields_data_nodes', 8 );
|
||||
|
||||
// =============================================================================
|
||||
// SHOW UNLOCKS SECTION
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Unlock password-protected posts for user
|
||||
*
|
||||
* @since 5.16.0
|
||||
*
|
||||
* @param WP_User $profile_user The profile user object. Not necessarily the one
|
||||
* currently editing the profile!
|
||||
*/
|
||||
|
||||
function fictioneer_admin_profile_post_unlocks( $profile_user ) {
|
||||
// Check permissions
|
||||
if ( ! current_user_can( 'manage_options' ) && ! current_user_can( 'fcn_unlock_posts' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'edit_users' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup
|
||||
$unlocks = get_user_meta( $profile_user->ID, 'fictioneer_post_unlocks', true ) ?: [];
|
||||
$unlocks = is_array( $unlocks ) ? $unlocks : [];
|
||||
|
||||
// Post data
|
||||
$posts = [];
|
||||
$post_type_labels = array(
|
||||
'post' => _x( 'Post', 'Post type label.', 'fictioneer' ),
|
||||
'page' => _x( 'Page', 'Post type label.', 'fictioneer' ),
|
||||
'fcn_story' => _x( 'Story', 'Post type label.', 'fictioneer' ),
|
||||
'fcn_chapter' => _x( 'Chapter', 'Post type label.', 'fictioneer' ),
|
||||
'fcn_collection' => _x( 'Collection', 'Post type label.', 'fictioneer' ),
|
||||
'fcn_recommendation' => _x( 'Rec', 'Post type label.', 'fictioneer' )
|
||||
);
|
||||
|
||||
if ( $unlocks ) {
|
||||
$query = new WP_Query(
|
||||
array(
|
||||
'post_type'=> 'any',
|
||||
'post_status'=> 'any',
|
||||
'posts_per_page' => -1,
|
||||
'post__in' => $unlocks,
|
||||
'update_post_meta_cache' => false, // Improve performance
|
||||
'update_post_term_cache' => false, // Improve performance
|
||||
'no_found_rows' => true // Improve performance
|
||||
)
|
||||
);
|
||||
|
||||
$posts = $query->posts;
|
||||
|
||||
// Prime author cache
|
||||
if ( function_exists( 'update_post_author_caches' ) ) {
|
||||
update_post_author_caches( $posts );
|
||||
}
|
||||
}
|
||||
|
||||
// Start HTML ---> ?>
|
||||
<tr class="user-unlock-posts-wrap">
|
||||
|
||||
<th><?php _e( 'Unlock Posts', 'fictioneer' ); ?></th>
|
||||
|
||||
<td class="unlock-posts" data-controller="fcn-unlock-posts">
|
||||
<fieldset>
|
||||
|
||||
<?php wp_nonce_field( 'search_posts', 'unlock_posts_nonce' ); ?>
|
||||
|
||||
<template data-target="fcn-unlock-posts-item-template">
|
||||
<div class="unlock-posts__item" title="" data-target="fcn-unlock-posts-item" data-post-id="0">
|
||||
<input type="hidden" name="fictioneer_post_unlocks[]" value="">
|
||||
<span class="unlock-posts__item-title"></span>
|
||||
<span class="unlock-posts__item-meta"></span>
|
||||
<button type="button" class="unlock-posts__delete" data-target="fcn-unlock-posts-delete"><span class="dashicons dashicons-no-alt"></span></button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<p>
|
||||
<?php _e( 'Allow the user to ignore the password of selected posts. Chapters inherit the unlock from the story.', 'fictioneer' ); ?>
|
||||
</p>
|
||||
|
||||
<div class="unlock-posts__search">
|
||||
|
||||
<div class="unlock-posts__search-form">
|
||||
<input type="search" class="unlock-posts__search-input regular-text" name="unlock_search" data-target="fcn-unlock-posts-search" placeholder="<?php _e( 'Search posts to unlock…', 'fictioneer' ); ?>">
|
||||
<select class="unlock-posts__search-select" name="unlock_select_type" data-target="fcn-unlock-posts-select" >
|
||||
<option value="0" selected><?php _e( 'Any', 'fictioneer' ); ?></option>
|
||||
<option value="post"><?php _e( 'Post', 'fictioneer' ); ?></option>
|
||||
<option value="page"><?php _e( 'Page', 'fictioneer' ); ?></option>
|
||||
<option value="fcn_story"><?php _e( 'Story', 'fictioneer' ); ?></option>
|
||||
<option value="fcn_chapter"><?php _e( 'Chapter', 'fictioneer' ); ?></option>
|
||||
<option value="fcn_collection"><?php _e( 'Collection', 'fictioneer' ); ?></option>
|
||||
<option value="fcn_recommendation"><?php _e( 'Recommendation', 'fictioneer' ); ?></option>
|
||||
</select>
|
||||
<i class="fa-solid fa-spinner fa-spin" style="--fa-animation-duration: .8s;"></i>
|
||||
</div>
|
||||
|
||||
<div class="unlock-posts__search-results" data-target="fcn-unlock-posts-search-results"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="unlock-posts__unlocked-posts" data-target="fcn-unlock-posts-selected">
|
||||
|
||||
<input type="hidden" name="fictioneer_post_unlocks" value="0">
|
||||
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<?php
|
||||
$type = $post_type_labels[ $post->post_type ] ?? '';
|
||||
$title = fictioneer_get_safe_title( $post->ID );
|
||||
$item_title = sprintf(
|
||||
_x( 'Author: %s | Title: %s', 'Unlock post item.', 'fictioneer' ),
|
||||
get_the_author_meta( 'display_name', $post->post_author ) ?: __( 'n/a', 'fictioneer' ),
|
||||
$title
|
||||
);
|
||||
?>
|
||||
<div class="unlock-posts__item" title="<?php echo esc_attr( $item_title ); ?>" data-target="fcn-unlock-posts-item" data-post-id="<?php echo $post->ID; ?>">
|
||||
<input type="hidden" name="fictioneer_post_unlocks[]" value="<?php echo $post->ID; ?>">
|
||||
<span class="unlock-posts__item-title"><?php echo $title; ?></span>
|
||||
<span class="unlock-posts__item-meta"><?php printf( _x( '(%s | %s)', 'Unlock post item meta: Type | ID.', 'fictioneer' ), $type, $post->ID ); ?></span>
|
||||
<button type="button" class="unlock-posts__delete" data-target="fcn-unlock-posts-delete"><span class="dashicons dashicons-no-alt"></span></button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<?php // <--- End HTML
|
||||
}
|
||||
add_action( 'fictioneer_admin_user_sections', 'fictioneer_admin_profile_post_unlocks', 9 );
|
||||
|
||||
// =============================================================================
|
||||
// SHOW MODERATION SECTION
|
||||
// =============================================================================
|
||||
|
@ -1167,4 +1167,135 @@ function fictioneer_ajax_get_user_data() {
|
||||
}
|
||||
add_action( 'wp_ajax_fictioneer_ajax_get_user_data', 'fictioneer_ajax_get_user_data' );
|
||||
|
||||
?>
|
||||
// =============================================================================
|
||||
// UNLOCK POSTS - AJAX
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Searches for posts to unlock via AJAX
|
||||
*
|
||||
* @since 5.16.0
|
||||
*/
|
||||
|
||||
function fictioneer_ajax_search_posts_to_unlock() {
|
||||
// Validations
|
||||
$user = fictioneer_get_validated_ajax_user( 'nonce', 'search_posts' );
|
||||
|
||||
if ( ! $user ) {
|
||||
wp_send_json_error( array( 'error' => __( 'Request did not pass validation.', 'fictioneer' ) ) );
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) && ! current_user_can( 'fcn_unlock_posts' ) ) {
|
||||
wp_send_json_error( array( 'error' => __( 'Insufficient permissions.', 'fictioneer' ) ) );
|
||||
}
|
||||
|
||||
// Setup
|
||||
$search = sanitize_text_field( $_REQUEST['search'] ?? '' );
|
||||
$type = sanitize_key( $_REQUEST['type'] ?? '' );
|
||||
$output = [];
|
||||
|
||||
// Empty?
|
||||
if ( empty( $search ) ) {
|
||||
wp_send_json_success( array( 'html' => '' ) );
|
||||
}
|
||||
|
||||
// Query
|
||||
$posts = new WP_Query(
|
||||
array(
|
||||
'post_type' => $type ?: ['post', 'page', 'fcn_story', 'fcn_chapter', 'fcn_collection', 'fcn_recommendation'],
|
||||
'post_status' => 'any',
|
||||
'orderby' => 'date',
|
||||
'order' => 'desc',
|
||||
'posts_per_page' => 20,
|
||||
's' => $search,
|
||||
'update_post_meta_cache' => false, // Improve performance
|
||||
'update_post_term_cache' => false, // Improve performance
|
||||
'no_found_rows' => true // Improve performance
|
||||
)
|
||||
);
|
||||
|
||||
// Prime author cache
|
||||
if ( function_exists( 'update_post_author_caches' ) ) {
|
||||
update_post_author_caches( $posts->posts );
|
||||
}
|
||||
|
||||
// Search result
|
||||
if ( ! $posts->posts ) {
|
||||
wp_send_json_success( array( 'html' => '' ) );
|
||||
} else {
|
||||
// Labels
|
||||
$post_type_labels = array(
|
||||
'post' => _x( 'Post', 'Post type label.', 'fictioneer' ),
|
||||
'page' => _x( 'Page', 'Post type label.', 'fictioneer' ),
|
||||
'fcn_story' => _x( 'Story', 'Post type label.', 'fictioneer' ),
|
||||
'fcn_chapter' => _x( 'Chapter', 'Post type label.', 'fictioneer' ),
|
||||
'fcn_collection' => _x( 'Collection', 'Post type label.', 'fictioneer' ),
|
||||
'fcn_recommendation' => _x( 'Rec', 'Post type label.', 'fictioneer' )
|
||||
);
|
||||
|
||||
foreach ( $posts->posts as $post ) {
|
||||
$type = $post_type_labels[ $post->post_type ] ?? '';
|
||||
$title = fictioneer_get_safe_title( $post->ID );
|
||||
$item_title = sprintf(
|
||||
_x( 'Author: %s | Title: %s', 'Unlock post item.', 'fictioneer' ),
|
||||
get_the_author_meta( 'display_name', $post->post_author ) ?: __( 'n/a', 'fictioneer' ),
|
||||
$title
|
||||
);
|
||||
|
||||
$output[] = '<div class="unlock-posts__item _searched" title="' . esc_attr( $item_title ) . '" data-target="fcn-unlock-posts-search-item" data-post-id="' . $post->ID . '"><span class="unlock-posts__item-title">' . $title . '</span> <span class="unlock-posts__item-meta">' . sprintf( _x( '(%s | %s)', 'Unlock post item meta: Type | ID.', 'fictioneer' ), $type, $post->ID ) . '</span></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Response
|
||||
wp_send_json_success( array( 'html' => implode( '', $output ) ) );
|
||||
}
|
||||
add_action( 'wp_ajax_fictioneer_ajax_search_posts_to_unlock', 'fictioneer_ajax_search_posts_to_unlock' );
|
||||
|
||||
/**
|
||||
* Update unlocked posts for user
|
||||
*
|
||||
* @since 5.16.0
|
||||
*
|
||||
* @param int $updated_user_id The ID of the updated user.
|
||||
*/
|
||||
|
||||
function fictioneer_update_admin_unlocked_posts( $updated_user_id ) {
|
||||
// Check permissions
|
||||
if ( ! current_user_can( 'manage_options' ) && ! current_user_can( 'fcn_unlock_posts' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'edit_users' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup
|
||||
$admin_protection = fictioneer_is_admin( $updated_user_id ) && get_current_user_id() !== $updated_user_id;
|
||||
|
||||
// Check if protected, sanitize, validate, and update...
|
||||
if ( ! $admin_protection && isset( $_POST['fictioneer_post_unlocks'] ) ) {
|
||||
$post_ids = $_POST['fictioneer_post_unlocks'];
|
||||
$post_ids = is_array( $post_ids ) ? $post_ids : [];
|
||||
$post_ids = array_map( 'absint', $post_ids );
|
||||
$post_ids = array_unique( $post_ids );
|
||||
|
||||
$query = new WP_Query(
|
||||
array(
|
||||
'post_type'=> ['post', 'page', 'fcn_story', 'fcn_chapter', 'fcn_collection', 'fcn_recommendation'],
|
||||
'post_status'=> 'any',
|
||||
'posts_per_page' => -1,
|
||||
'post__in' => $post_ids ?: [0],
|
||||
'fields' => 'ids',
|
||||
'update_post_meta_cache' => false, // Improve performance
|
||||
'update_post_term_cache' => false, // Improve performance
|
||||
'no_found_rows' => true // Improve performance
|
||||
)
|
||||
);
|
||||
|
||||
$post_ids = array_map( 'strval', $query->posts );
|
||||
|
||||
fictioneer_update_user_meta( $updated_user_id, 'fictioneer_post_unlocks', $post_ids );
|
||||
}
|
||||
}
|
||||
add_action( 'personal_options_update', 'fictioneer_update_admin_unlocked_posts' );
|
||||
add_action( 'edit_user_profile_update', 'fictioneer_update_admin_unlocked_posts' );
|
||||
|
2
js/Sortable-1.15.2.min.js
vendored
Normal file
2
js/Sortable-1.15.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
js/admin.min.js
vendored
2
js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
2
js/ajax-bookshelf.min.js
vendored
2
js/ajax-bookshelf.min.js
vendored
@ -1 +1 @@
|
||||
const fcn_bookshelfTarget=_$$$("ajax-bookshelf-target");function fcn_getBookshelfContent(){return fcn_parseJSON(localStorage.getItem("fcnBookshelfContent"))??{html:{},count:{}}}function fcn_updateBookshelfView(e=null,t=null,o=null,n=!1){let a=fcn_getBookshelfContent();const s=(e=e??fcn_bookshelfTarget.dataset.action)+(t=t??fcn_bookshelfTarget.dataset.page)+(o=o??fcn_bookshelfTarget.dataset.order);if(!a.hasOwnProperty("timestamp")||a.timestamp+6e4<Date.now())return localStorage.removeItem("fcnBookshelfContent"),a={html:{},count:{}},void fcn_fetchBookshelfPart(e,t,o,n);a.hasOwnProperty("html")&&a.html.hasOwnProperty(s)?(fcn_bookshelfTarget.innerHTML=a.html[s],fcn_bookshelfTarget.classList.remove("ajax-in-progress"),fcn_bookshelfTarget.dataset.page=t,_$(".item-number").innerHTML=`(${a.count[e]})`,n&&_$$$("main").scrollIntoView({behavior:"smooth"})):fcn_fetchBookshelfPart(e,t,o,n)}function fcn_browseBookshelfPage(e){fcn_bookshelfTarget.classList.add("ajax-in-progress"),fcn_updateBookshelfView(null,e,null,!0),history.pushState({},"",fcn_buildUrl({tab:fcn_bookshelfTarget.dataset.tab,pg:e,order:fcn_bookshelfTarget.dataset.order}).href)}function fcn_fetchBookshelfPart(e,t,o,n=!1){const a=e+t+o,s=fcn_getBookshelfContent();fcn_ajaxGet({action:e,fcn_fast_ajax:1,page:t,order:o}).then((o=>{o.success?(s.timestamp=Date.now(),s.html[a]=o.data.html,s.count[e]=o.data.count,localStorage.setItem("fcnBookshelfContent",JSON.stringify(s)),fcn_bookshelfTarget.innerHTML=o.data.html,fcn_bookshelfTarget.dataset.page=t,_$(".item-number").innerHTML=`(${o.data.count})`):(fcn_bookshelfTarget.innerHTML="",fcn_bookshelfTarget.appendChild(fcn_buildErrorNotice(o.data.error)))})).catch((e=>{_$(".item-number").innerHTML="",fcn_bookshelfTarget.innerHTML="",fcn_bookshelfTarget.appendChild(fcn_buildErrorNotice(`${e.status}: ${e.statusText}`))})).then((()=>{fcn_bookshelfTarget.classList.remove("ajax-in-progress"),n&&_$$$("main").scrollIntoView({behavior:"smooth"})}))}fcn_bookshelfTarget&&(fcn_theRoot.dataset.ajaxAuth?document.addEventListener("fcnAuthReady",(()=>{fcn_updateBookshelfView()})):fcn_updateBookshelfView()),_$(".bookshelf__list")?.addEventListener("click",(e=>{const t=e.target.closest(".page-numbers[data-page]");t&&fcn_browseBookshelfPage(t.dataset.page)}));
|
||||
const fcn_bookshelfTarget=_$$$("ajax-bookshelf-target");function fcn_getBookshelfContent(){return fcn_parseJSON(localStorage.getItem("fcnBookshelfContent"))??{html:{},count:{}}}function fcn_updateBookshelfView(e=null,t=null,o=null,n=!1){let a=fcn_getBookshelfContent();const s=(e=e??fcn_bookshelfTarget.dataset.action)+(t=t??fcn_bookshelfTarget.dataset.page)+(o=o??fcn_bookshelfTarget.dataset.order);if(!a.timestamp||a.timestamp+6e4<Date.now())return localStorage.removeItem("fcnBookshelfContent"),a={html:{},count:{}},void fcn_fetchBookshelfPart(e,t,o,n);a.html&&a.html[s]?(fcn_bookshelfTarget.innerHTML=a.html[s],fcn_bookshelfTarget.classList.remove("ajax-in-progress"),fcn_bookshelfTarget.dataset.page=t,_$(".item-number").innerHTML=`(${a.count[e]})`,n&&_$$$("main").scrollIntoView({behavior:"smooth"})):fcn_fetchBookshelfPart(e,t,o,n)}function fcn_browseBookshelfPage(e){fcn_bookshelfTarget.classList.add("ajax-in-progress"),fcn_updateBookshelfView(null,e,null,!0),history.pushState({},"",fcn_buildUrl({tab:fcn_bookshelfTarget.dataset.tab,pg:e,order:fcn_bookshelfTarget.dataset.order}).href)}function fcn_fetchBookshelfPart(e,t,o,n=!1){const a=e+t+o,s=fcn_getBookshelfContent();fcn_ajaxGet({action:e,fcn_fast_ajax:1,page:t,order:o}).then((o=>{o.success?(s.timestamp=Date.now(),s.html[a]=o.data.html,s.count[e]=o.data.count,localStorage.setItem("fcnBookshelfContent",JSON.stringify(s)),fcn_bookshelfTarget.innerHTML=o.data.html,fcn_bookshelfTarget.dataset.page=t,_$(".item-number").innerHTML=`(${o.data.count})`):(fcn_bookshelfTarget.innerHTML="",fcn_bookshelfTarget.appendChild(fcn_buildErrorNotice(o.data.error)))})).catch((e=>{_$(".item-number").innerHTML="",fcn_bookshelfTarget.innerHTML="",fcn_bookshelfTarget.appendChild(fcn_buildErrorNotice(`${e.status}: ${e.statusText}`))})).then((()=>{fcn_bookshelfTarget.classList.remove("ajax-in-progress"),n&&_$$$("main").scrollIntoView({behavior:"smooth"})}))}fcn_bookshelfTarget&&(fcn_theRoot.dataset.ajaxAuth?document.addEventListener("fcnAuthReady",(()=>{fcn_updateBookshelfView()})):fcn_updateBookshelfView()),_$(".bookshelf__list")?.addEventListener("click",(e=>{const t=e.target.closest(".page-numbers[data-page]");t&&fcn_browseBookshelfPage(t.dataset.page)}));
|
2
js/ajax-comments.min.js
vendored
2
js/ajax-comments.min.js
vendored
@ -1 +1 @@
|
||||
const fcn_commentSection=_$("#comments[data-ajax-comments]");function fcn_getCommentSection(e=null,t=null,n=null,o=!1){if(!fcn_commentSection)return;let c,m="",a=_$(fictioneer_comments.form_selector??"#comment");if(a&&(m=a.value),fcn_commentSection.classList.contains("ajax-in-progress"))return;if(fcn_commentSection.classList.add("ajax-in-progress"),t||(t=fcn_urlParams.pg??1),n||(n=n??fcn_commentSection.dataset.order??"desc"),!fcn_commentSection)return;const r={action:"fictioneer_ajax_get_comment_section",post_id:e??fcn_commentSection.dataset.postId,page:parseInt(t),corder:n};fcn_urlParams.commentcode&&(r.commentcode=fcn_urlParams.commentcode),fcn_ajaxGet(r).then((e=>{if(e.success){t=e.data.page,fcn_commentSection.dataset.page=t;const c=document.createElement("div");if(c.innerHTML=e.data.html,c.querySelector("#comment_post_ID")){c.querySelector("#comment_post_ID").value=e.data.postId,c.querySelector("#cancel-comment-reply-link").href="#respond";const t=c.querySelector(".logout-link");t&&(t.href=fcn_commentSection.dataset.logoutUrl)}fcn_commentSection.innerHTML=c.innerHTML,c.remove(),e.data.disabled||(a=_$(fictioneer_comments.form_selector??"#comment"),a.value=m,fcn_applyCommentStack(a)),fcn_addCommentMouseleaveEvents(),fcn_addCommentFormEvents(),fcn_bindAJAXCommentSubmit(),fcn_addJSTrap(),fcn_revealEditButton(),fcn_revealDeleteButton();const r=location.hash.includes("#comment")?location.hash:".respond",s=document.querySelector(r)??_$$$("respond");o&&s.scrollIntoView({behavior:"smooth"});const i=window.location.protocol+"//"+window.location.host+window.location.pathname;let d="";fcn_urlParams.commentcode&&(d+=`?commentcode=${fcn_urlParams.commentcode}`),t>1&&(d+=d.length>1?`&pg=${t}`:`?pg=${t}`),"desc"!=n&&(d+=d.length>1?`&corder=${n}`:`?corder=${n}`),window.history.pushState({path:i},"",i+d+location.hash)}else c=fcn_buildErrorNotice(e.data.error)})).catch((e=>{c=fcn_buildErrorNotice(e)})).then((()=>{fcn_commentSection.classList.remove("ajax-in-progress"),c&&(fcn_commentSection.innerHTML="",fcn_commentSection.appendChild(c))}))}function fcn_reloadCommentsPage(e=null){fcn_getCommentSection(null,e,null,!0)}function fcn_jumpToCommentPage(){const e=parseInt(window.prompt(fictioneer_tl.notification.enterPageNumber));e>0&&fcn_reloadCommentsPage(e)}var fct_commentSectionObserver;function fcn_setupCommentSectionObserver(){fct_commentSectionObserver=new IntersectionObserver((([e])=>{e.isIntersecting&&(fcn_getCommentSection(),fct_commentSectionObserver.disconnect())}),{rootMargin:"450px",threshold:1}),fcn_commentSection&&fct_commentSectionObserver.observe(fcn_commentSection)}function fcn_loadCommentEarly(){fcn_commentSection&&location.hash.includes("#comment")&&(_$(fictioneer_comments.form_selector??"#comment")||(fct_commentSectionObserver.disconnect(),fcn_reloadCommentsPage()))}function fcn_toggleCommentOrder(e){const t=e.closest(".fictioneer-comments"),n="desc"==t.dataset.order;t.dataset.order=n?"asc":"desc",e.classList.toggle("_on",!n),e.classList.toggle("_off",n),fcn_reloadCommentsPage(t.dataset.page)}fcn_theRoot.dataset.ajaxAuth?document.addEventListener("fcnAuthReady",(()=>{fcn_setupCommentSectionObserver()})):fcn_setupCommentSectionObserver(),fcn_theRoot.dataset.ajaxAuth?document.addEventListener("fcnAuthReady",(()=>{fcn_loadCommentEarly()})):fcn_loadCommentEarly(),_$(".fictioneer-comments")?.addEventListener("click",(e=>{if(e.target.closest("button[data-page-jump]"))return void fcn_jumpToCommentPage();const t=e.target.closest("button[data-page]");if(t)return void fcn_reloadCommentsPage(t.dataset.page);const n=e.target.closest("button[data-toggle-order]");n&&fcn_toggleCommentOrder(n)}));
|
||||
const fcn_commentSection=_$("#comments[data-ajax-comments]");function fcn_getCommentSection(e=null,t=null,n=null,o=!1){if(!fcn_commentSection)return;let c,m="",a=_$(fictioneer_comments.form_selector??"#comment");if(a&&(m=a.value),fcn_commentSection.classList.contains("ajax-in-progress"))return;if(fcn_commentSection.classList.add("ajax-in-progress"),t||(t=fcn_urlParams.pg??1),n||(n=n??fcn_commentSection.dataset.order??"desc"),!fcn_commentSection)return;const r={action:"fictioneer_ajax_get_comment_section",post_id:e??fcn_commentSection.dataset.postId,page:parseInt(t),corder:n,fcn_fast_comment_ajax:1};fcn_urlParams.commentcode&&(r.commentcode=fcn_urlParams.commentcode),fcn_ajaxGet(r).then((e=>{if(e.success){t=e.data.page,fcn_commentSection.dataset.page=t;const c=document.createElement("div");if(c.innerHTML=e.data.html,c.querySelector("#comment_post_ID")){c.querySelector("#comment_post_ID").value=e.data.postId,c.querySelector("#cancel-comment-reply-link").href="#respond";const t=c.querySelector(".logout-link");t&&(t.href=fcn_commentSection.dataset.logoutUrl)}fcn_commentSection.innerHTML=c.innerHTML,c.remove(),e.data.disabled||(a=_$(fictioneer_comments.form_selector??"#comment"),a.value=m,fcn_applyCommentStack(a)),fcn_addCommentMouseleaveEvents(),fcn_addCommentFormEvents(),fcn_bindAJAXCommentSubmit(),fcn_addJSTrap(),fcn_revealEditButton(),fcn_revealDeleteButton();const r=location.hash.includes("#comment")?location.hash:".respond",s=document.querySelector(r)??_$$$("respond");o&&s.scrollIntoView({behavior:"smooth"});const i=window.location.protocol+"//"+window.location.host+window.location.pathname;let d="";fcn_urlParams.commentcode&&(d+=`?commentcode=${fcn_urlParams.commentcode}`),t>1&&(d+=d.length>1?`&pg=${t}`:`?pg=${t}`),"desc"!=n&&(d+=d.length>1?`&corder=${n}`:`?corder=${n}`),window.history.pushState({path:i},"",i+d+location.hash)}else c=fcn_buildErrorNotice(e.data.error)})).catch((e=>{c=fcn_buildErrorNotice(e)})).then((()=>{fcn_commentSection.classList.remove("ajax-in-progress"),c&&(fcn_commentSection.innerHTML="",fcn_commentSection.appendChild(c))}))}function fcn_reloadCommentsPage(e=null){fcn_getCommentSection(null,e,null,!0)}function fcn_jumpToCommentPage(){const e=parseInt(window.prompt(fictioneer_tl.notification.enterPageNumber));e>0&&fcn_reloadCommentsPage(e)}var fct_commentSectionObserver;function fcn_setupCommentSectionObserver(){fct_commentSectionObserver=new IntersectionObserver((([e])=>{e.isIntersecting&&(fcn_getCommentSection(),fct_commentSectionObserver.disconnect())}),{rootMargin:"450px",threshold:1}),fcn_commentSection&&fct_commentSectionObserver.observe(fcn_commentSection)}function fcn_loadCommentEarly(){fcn_commentSection&&location.hash.includes("#comment")&&(_$(fictioneer_comments.form_selector??"#comment")||(fct_commentSectionObserver.disconnect(),fcn_reloadCommentsPage()))}function fcn_toggleCommentOrder(e){const t=e.closest(".fictioneer-comments"),n="desc"==t.dataset.order;t.dataset.order=n?"asc":"desc",e.classList.toggle("_on",!n),e.classList.toggle("_off",n),fcn_reloadCommentsPage(t.dataset.page)}fcn_theRoot.dataset.ajaxAuth?document.addEventListener("fcnAuthReady",(()=>{fcn_setupCommentSectionObserver()})):fcn_setupCommentSectionObserver(),fcn_theRoot.dataset.ajaxAuth?document.addEventListener("fcnAuthReady",(()=>{fcn_loadCommentEarly()})):fcn_loadCommentEarly(),_$(".fictioneer-comments")?.addEventListener("click",(e=>{if(e.target.closest("button[data-page-jump]"))return void fcn_jumpToCommentPage();const t=e.target.closest("button[data-page]");if(t)return void fcn_reloadCommentsPage(t.dataset.page);const n=e.target.closest("button[data-toggle-order]");n&&fcn_toggleCommentOrder(n)}));
|
2
js/application.min.js
vendored
2
js/application.min.js
vendored
File diff suppressed because one or more lines are too long
2
js/chapter.min.js
vendored
2
js/chapter.min.js
vendored
File diff suppressed because one or more lines are too long
2
js/checkmarks.min.js
vendored
2
js/checkmarks.min.js
vendored
@ -1 +1 @@
|
||||
var fcn_checkmarks,fcn_userCheckmarksTimeout;function fcn_initializeCheckmarks(a){const t=a.detail.data.checkmarks;!1!==t&&(Array.isArray(t.data)&&0===t.data.length&&(t.data={}),fcn_checkmarks=t,fcn_updateCheckmarksView(),localStorage.removeItem("fcnBookshelfContent"),_$$("button.checkmark").forEach((a=>{a.addEventListener("click",(a=>{fcn_clickCheckmark(a.currentTarget)}))})))}function fcn_toggleCheckmark(a,t,e=null,c=null,s="toggle"){const r=fcn_getUserData();if(fcn_checkmarks&&r.checkmarks){if(localStorage.removeItem("fcnBookshelfContent"),"toggle"===s&&JSON.stringify(fcn_checkmarks.data[a])!==JSON.stringify(r.checkmarks.data[a]))return fcn_checkmarks=r.checkmarks,fcn_showNotification(fictioneer_tl.notification.checkmarksResynchronized),void fcn_updateCheckmarksView();if(fcn_checkmarks.data.hasOwnProperty(a)||(fcn_checkmarks.data[a]=[]),r.checkmarks.data.hasOwnProperty(a)||(r.checkmarks.data[a]=[]),e&&"progress"===t&&!fcn_checkmarks.data[a].includes(e)&&fcn_checkmarks.data[a].push(e),e&&"chapter"===t)if(!fcn_checkmarks.data[a].includes(e)&&"unset"!==s||"set"===s)fcn_checkmarks.data[a].push(e),c&&(c.classList.add("marked"),c.setAttribute("aria-checked",!0));else{fcn_removeItemOnce(fcn_checkmarks.data[a],e),c&&(c.classList.remove("marked"),c.setAttribute("aria-checked",!1)),fcn_removeItemOnce(fcn_checkmarks.data[a],a);const t=_$('button[data-type="story"]');t&&(t.classList.remove("marked"),t.setAttribute("aria-checked",!1))}if("story"===t){const t=(fcn_checkmarks.data[a].includes(a)||"unset"===s)&&"set"!==s;fcn_checkmarks.data[a]=[],t||(_$$("button.checkmark").forEach((t=>{fcn_checkmarks.data[a].push(parseInt(t.dataset.id))})),fcn_checkmarks.data[a].includes(a)||fcn_checkmarks.data[a].push(a))}fcn_checkmarks.data[a]=fcn_checkmarks.data[a].filter(((a,t,e)=>e.indexOf(a)==t)),r.checkmarks.data[a]=fcn_checkmarks.data[a],r.lastLoaded=0,fcn_setUserData(r),fcn_updateCheckmarksView(),clearTimeout(fcn_userCheckmarksTimeout),fcn_userCheckmarksTimeout=setTimeout((()=>{fcn_updateCheckmarks(a,fcn_checkmarks.data[a])}),fictioneer_ajax.post_debounce_rate)}}function fcn_clickCheckmark(a){fcn_toggleCheckmark(parseInt(a.dataset.storyId),a.dataset.type,parseInt(a.dataset.id),a)}function fcn_updateCheckmarks(a,t=null){t=t||fcn_getUserData().checkmarks.data[a],fcn_ajaxPost({action:"fictioneer_ajax_set_checkmark",fcn_fast_ajax:1,story_id:a,update:t.join(" ")}).then((a=>{a.data.error&&fcn_showNotification(a.data.error,3,"warning")})).catch((a=>{a.status&&a.statusText&&fcn_showNotification(`${a.status}: ${a.statusText}`,5,"warning")}))}function fcn_updateCheckmarksView(){const a=fcn_getUserData(),t=a.checkmarks;if(!t)return;const e=parseInt(fcn_inlineStorage.storyId);if(e){const c=t.data.hasOwnProperty(e)&&t.data[e].includes(e);if(c){let c=!1;_$$("button.checkmark").forEach((a=>{const s=parseInt(a.dataset.id);t.data[e].includes(s)||(t.data[e].push(s),c=!0)})),c&&(a.checkmarks=t,fcn_setUserData(a),fcn_updateCheckmarks(e,t.data[e]))}_$$$("ribbon-read")?.classList.toggle("hidden",!c)}_$$("button.checkmark").forEach((a=>{const e=parseInt(a.dataset.storyId);if(t.data.hasOwnProperty(e)){const c=t.data[e].includes(parseInt(a.dataset.id));a.classList.toggle("marked",c),a.setAttribute("aria-checked",c)}})),_$$(".card").forEach((a=>{const e=parseInt(a.dataset.storyId),c=t.data.hasOwnProperty(e)&&(t.data[e].includes(parseInt(a.dataset.checkId))||t.data[e].includes(e));a.classList.toggle("has-checkmark",c)}))}document.addEventListener("fcnUserDataReady",(a=>{fcn_initializeCheckmarks(a)}));
|
||||
var fcn_checkmarks,fcn_userCheckmarksTimeout;function fcn_initializeCheckmarks(a){const c=a.detail.data.checkmarks;!1!==c&&(Array.isArray(c.data)&&0===c.data.length&&(c.data={}),fcn_checkmarks=c,fcn_updateCheckmarksView(),localStorage.removeItem("fcnBookshelfContent"),_$$("button.checkmark").forEach((a=>{a.addEventListener("click",(a=>{fcn_clickCheckmark(a.currentTarget)}))})))}function fcn_toggleCheckmark(a,c,t=null,e=null,s="toggle"){const n=fcn_getUserData();if(fcn_checkmarks&&n.checkmarks){if(localStorage.removeItem("fcnBookshelfContent"),"toggle"===s&&JSON.stringify(fcn_checkmarks.data[a])!==JSON.stringify(n.checkmarks.data[a]))return fcn_checkmarks=n.checkmarks,fcn_showNotification(fictioneer_tl.notification.checkmarksResynchronized),void fcn_updateCheckmarksView();if(fcn_checkmarks.data[a]||(fcn_checkmarks.data[a]=[]),n.checkmarks.data[a]||(n.checkmarks.data[a]=[]),t&&"progress"===c&&!fcn_checkmarks.data[a].includes(t)&&fcn_checkmarks.data[a].push(t),t&&"chapter"===c)if(!fcn_checkmarks.data[a].includes(t)&&"unset"!==s||"set"===s)fcn_checkmarks.data[a].push(t),e&&(e.classList.add("marked"),e.setAttribute("aria-checked",!0));else{fcn_removeItemOnce(fcn_checkmarks.data[a],t),e&&(e.classList.remove("marked"),e.setAttribute("aria-checked",!1)),fcn_removeItemOnce(fcn_checkmarks.data[a],a);const c=_$('button[data-type="story"]');c&&(c.classList.remove("marked"),c.setAttribute("aria-checked",!1))}if("story"===c){const c=(fcn_checkmarks.data[a].includes(a)||"unset"===s)&&"set"!==s;fcn_checkmarks.data[a]=[],c||(_$$("button.checkmark").forEach((c=>{fcn_checkmarks.data[a].push(parseInt(c.dataset.id))})),fcn_checkmarks.data[a].includes(a)||fcn_checkmarks.data[a].push(a))}fcn_checkmarks.data[a]=fcn_checkmarks.data[a].filter(((a,c,t)=>t.indexOf(a)==c)),n.checkmarks.data[a]=fcn_checkmarks.data[a],n.lastLoaded=0,fcn_setUserData(n),fcn_updateCheckmarksView(),clearTimeout(fcn_userCheckmarksTimeout),fcn_userCheckmarksTimeout=setTimeout((()=>{fcn_updateCheckmarks(a,fcn_checkmarks.data[a])}),fictioneer_ajax.post_debounce_rate)}}function fcn_clickCheckmark(a){fcn_toggleCheckmark(parseInt(a.dataset.storyId),a.dataset.type,parseInt(a.dataset.id),a)}function fcn_updateCheckmarks(a,c=null){c=c||fcn_getUserData().checkmarks.data[a],fcn_ajaxPost({action:"fictioneer_ajax_set_checkmark",fcn_fast_ajax:1,story_id:a,update:c.join(" ")}).then((a=>{a.data.error&&fcn_showNotification(a.data.error,3,"warning")})).catch((a=>{a.status&&a.statusText&&fcn_showNotification(`${a.status}: ${a.statusText}`,5,"warning")}))}function fcn_updateCheckmarksView(){const a=fcn_getUserData(),c=a.checkmarks;if(!c)return;const t=parseInt(fcn_inlineStorage.storyId);if(t){const e=c.data[t]&&c.data[t].includes(t);if(e){let e=!1;_$$("button.checkmark").forEach((a=>{const s=parseInt(a.dataset.id);c.data[t].includes(s)||(c.data[t].push(s),e=!0)})),e&&(a.checkmarks=c,fcn_setUserData(a),fcn_updateCheckmarks(t,c.data[t]))}_$$$("ribbon-read")?.classList.toggle("hidden",!e)}_$$("button.checkmark").forEach((a=>{const t=parseInt(a.dataset.storyId);if(c.data[t]){const e=c.data[t].includes(parseInt(a.dataset.id));a.classList.toggle("marked",e),a.setAttribute("aria-checked",e)}})),_$$(".card").forEach((a=>{const t=parseInt(a.dataset.storyId),e=c.data[t]&&(c.data[t].includes(parseInt(a.dataset.checkId))||c.data[t].includes(t));a.classList.toggle("has-checkmark",e)}))}document.addEventListener("fcnUserDataReady",(a=>{fcn_initializeCheckmarks(a)}));
|
2
js/comments.min.js
vendored
2
js/comments.min.js
vendored
File diff suppressed because one or more lines are too long
10
js/complete.min.js
vendored
10
js/complete.min.js
vendored
File diff suppressed because one or more lines are too long
1
js/diff-match-patch.min.js
vendored
Normal file
1
js/diff-match-patch.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
js/follows.min.js
vendored
2
js/follows.min.js
vendored
@ -1 +1 @@
|
||||
const fcn_followsMenuItem=_$$$("follow-menu-button");var fcn_userFollowsTimeout,fcn_follows;function fcn_initializeFollows(o){const t=o.detail.data.follows;!1!==t&&(Array.isArray(t.data)&&0===t.data.length&&(t.data={}),fcn_follows=t,fcn_updateFollowsView(),localStorage.removeItem("fcnBookshelfContent"))}function fcn_toggleFollow(o){const t=fcn_getUserData();if(fcn_follows&&t.follows){if(localStorage.removeItem("fcnBookshelfContent"),JSON.stringify(fcn_follows.data[o])!==JSON.stringify(t.follows.data[o]))return fcn_follows=t.follows,fcn_showNotification(fictioneer_tl.notification.followsResynchronized),void fcn_updateFollowsView();fcn_follows.data.hasOwnProperty(o)?delete fcn_follows.data[o]:fcn_follows.data[o]={story_id:parseInt(o),timestamp:Date.now()},t.follows.data[o]=fcn_follows.data[o],t.lastLoaded=0,fcn_setUserData(t),fcn_updateFollowsView(),clearTimeout(fcn_userFollowsTimeout),fcn_userFollowsTimeout=setTimeout((()=>{fcn_ajaxPost({action:"fictioneer_ajax_toggle_follow",fcn_fast_ajax:1,story_id:o,set:fcn_follows.data.hasOwnProperty(o)}).then((o=>{o.data.error&&fcn_showNotification(o.data.error,5,"warning")})).catch((o=>{429===o.status?fcn_showNotification(fictioneer_tl.notification.slowDown,3,"warning"):o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning")}))}),fictioneer_ajax.post_debounce_rate)}}function fcn_updateFollowsView(){const o=fcn_getUserData();if(!fcn_follows||!o.follows)return;_$$(".button-follow-story").forEach((o=>{o.classList.toggle("_followed",fcn_follows?.data.hasOwnProperty(o.dataset.storyId))})),_$$(".card").forEach((o=>{o.classList.toggle("has-follow",fcn_follows?.data.hasOwnProperty(o.dataset.storyId))}));const t=parseInt(fcn_follows.new)>0;_$$(".mark-follows-read, .follows-alert-number, .mobile-menu-button").forEach((o=>{o.classList.toggle("_new",t),t>0&&(o.dataset.newCount=fcn_follows.new)}))}function fcn_setupFollowsHTML(){fcn_followsMenuItem.classList.contains("_loaded")||fcn_ajaxGet({action:"fictioneer_ajax_get_follows_notifications",fcn_fast_ajax:1}).then((o=>{if(o.data.html){const t=_$$$("follow-menu-scroll");t&&(t.innerHTML=o.data.html);const n=_$$$("mobile-menu-follows-list");n&&(n.innerHTML=o.data.html),!1===fcn_getUserData().loggedIn&&(fcn_prepareLogin(),fcn_fetchUserData())}})).catch((o=>{429===o.status?fcn_showNotification(fictioneer_tl.notification.slowDown,3,"warning"):o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning"),_$$$("follow-menu-scroll")?.remove(),_$$$("mobile-menu-follows-list")?.remove()})).then((()=>{fcn_followsMenuItem.classList.add("_loaded")}))}function fcn_markFollowsRead(){if(!fcn_followsMenuItem.classList.contains("_new")||!fcn_followsMenuItem.classList.contains("_loaded"))return;_$$(".mark-follows-read, .follows-alert-number, .follow-item, .mobile-menu-button").forEach((o=>{o.classList.remove("_new")}));const o=fcn_getUserData();o.new=0,o.lastLoaded=0,fcn_setUserData(o),fcn_ajaxPost({action:"fictioneer_ajax_mark_follows_read",fcn_fast_ajax:1}).catch((o=>{o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning")}))}document.addEventListener("fcnUserDataReady",(o=>{fcn_initializeFollows(o)})),fcn_followsMenuItem?.addEventListener("mouseover",(()=>{fcn_setupFollowsHTML()}),{once:!0}),fcn_followsMenuItem?.addEventListener("focus",(()=>{fcn_setupFollowsHTML()}),{once:!0}),_$('.mobile-menu__frame-button[data-frame-target="follows"]')?.addEventListener("click",(()=>{fcn_setupFollowsHTML()}),{once:!0}),_$$(".button-follow-story").forEach((o=>{o.addEventListener("click",(o=>{fcn_toggleFollow(o.currentTarget.dataset.storyId)}))})),_$$(".mark-follows-read").forEach((o=>{o.addEventListener("click",(()=>{fcn_markFollowsRead()}))}));
|
||||
const fcn_followsMenuItem=_$$$("follow-menu-button");var fcn_userFollowsTimeout,fcn_follows;function fcn_initializeFollows(o){const t=o.detail.data.follows;!1!==t&&(Array.isArray(t.data)&&0===t.data.length&&(t.data={}),fcn_follows=t,fcn_updateFollowsView(),localStorage.removeItem("fcnBookshelfContent"))}function fcn_toggleFollow(o){const t=fcn_getUserData();if(fcn_follows&&t.follows){if(localStorage.removeItem("fcnBookshelfContent"),JSON.stringify(fcn_follows.data[o])!==JSON.stringify(t.follows.data[o]))return fcn_follows=t.follows,fcn_showNotification(fictioneer_tl.notification.followsResynchronized),void fcn_updateFollowsView();fcn_follows.data[o]?delete fcn_follows.data[o]:fcn_follows.data[o]={story_id:parseInt(o),timestamp:Date.now()},t.follows.data[o]=fcn_follows.data[o],t.lastLoaded=0,fcn_setUserData(t),fcn_updateFollowsView(),clearTimeout(fcn_userFollowsTimeout),fcn_userFollowsTimeout=setTimeout((()=>{fcn_ajaxPost({action:"fictioneer_ajax_toggle_follow",fcn_fast_ajax:1,story_id:o,set:!!fcn_follows.data[o]}).then((o=>{o.data.error&&fcn_showNotification(o.data.error,5,"warning")})).catch((o=>{429===o.status?fcn_showNotification(fictioneer_tl.notification.slowDown,3,"warning"):o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning")}))}),fictioneer_ajax.post_debounce_rate)}}function fcn_updateFollowsView(){const o=fcn_getUserData();if(!fcn_follows||!o.follows)return;_$$(".button-follow-story").forEach((o=>{o.classList.toggle("_followed",!!fcn_follows?.data[o.dataset.storyId])})),_$$(".card").forEach((o=>{o.classList.toggle("has-follow",!!fcn_follows?.data[o.dataset.storyId])}));const t=parseInt(fcn_follows.new)>0;_$$(".mark-follows-read, .follows-alert-number, .mobile-menu-button").forEach((o=>{o.classList.toggle("_new",t),t>0&&(o.dataset.newCount=fcn_follows.new)}))}function fcn_setupFollowsHTML(){fcn_followsMenuItem.classList.contains("_loaded")||fcn_ajaxGet({action:"fictioneer_ajax_get_follows_notifications",fcn_fast_ajax:1}).then((o=>{if(o.data.html){const t=_$$$("follow-menu-scroll");t&&(t.innerHTML=o.data.html);const n=_$$$("mobile-menu-follows-list");n&&(n.innerHTML=o.data.html),!1===fcn_getUserData().loggedIn&&(fcn_prepareLogin(),fcn_fetchUserData())}})).catch((o=>{429===o.status?fcn_showNotification(fictioneer_tl.notification.slowDown,3,"warning"):o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning"),_$$$("follow-menu-scroll")?.remove(),_$$$("mobile-menu-follows-list")?.remove()})).then((()=>{fcn_followsMenuItem.classList.add("_loaded")}))}function fcn_markFollowsRead(){if(!fcn_followsMenuItem.classList.contains("_new")||!fcn_followsMenuItem.classList.contains("_loaded"))return;_$$(".mark-follows-read, .follows-alert-number, .follow-item, .mobile-menu-button").forEach((o=>{o.classList.remove("_new")}));const o=fcn_getUserData();o.new=0,o.lastLoaded=0,fcn_setUserData(o),fcn_ajaxPost({action:"fictioneer_ajax_mark_follows_read",fcn_fast_ajax:1}).catch((o=>{o.status&&o.statusText&&fcn_showNotification(`${o.status}: ${o.statusText}`,5,"warning")}))}document.addEventListener("fcnUserDataReady",(o=>{fcn_initializeFollows(o)})),fcn_followsMenuItem?.addEventListener("mouseover",(()=>{fcn_setupFollowsHTML()}),{once:!0}),fcn_followsMenuItem?.addEventListener("focus",(()=>{fcn_setupFollowsHTML()}),{once:!0}),_$('.mobile-menu__frame-button[data-frame-target="follows"]')?.addEventListener("click",(()=>{fcn_setupFollowsHTML()}),{once:!0}),_$$(".button-follow-story").forEach((o=>{o.addEventListener("click",(o=>{fcn_toggleFollow(o.currentTarget.dataset.storyId)}))})),_$$(".mark-follows-read").forEach((o=>{o.addEventListener("click",(()=>{fcn_markFollowsRead()}))}));
|
2
js/head-inline.min.js
vendored
2
js/head-inline.min.js
vendored
@ -1 +1 @@
|
||||
!function(){if("undefined"!=typeof localStorage){const e=localStorage.getItem("fcnLightmode"),t=document.documentElement;let a,o=localStorage.getItem("fcnSiteSettings");if(o&&(o=JSON.parse(o))&&null!==o&&"object"==typeof o){Object.entries(o).forEach((([e,r])=>{switch(e){case"minimal":t.classList.toggle("minimal",r);break;case"darken":a=r>=0?1+r**2:1-r**2,t.style.setProperty("--darken",`(${a} + var(--lightness-offset))`);break;case"saturation":case"font-lightness":case"font-saturation":a=r>=0?1+r**2:1-r**2,t.style.setProperty(`--${e}`,`(${a} + var(--${e}-offset))`);break;case"hue-rotate":a=Number.isInteger(o["hue-rotate"])?o["hue-rotate"]:0,t.style.setProperty("--hue-rotate",`(${a}deg + var(--hue-offset))`);break;default:t.classList.toggle(`no-${e}`,!r)}})),t.dataset.fontWeight=o.hasOwnProperty("font-weight")?o["font-weight"]:"default",t.dataset.theme=o.hasOwnProperty("site-theme")&&!t.dataset.forceChildTheme?o["site-theme"]:"default";let e=getComputedStyle(document.documentElement).getPropertyValue("--theme-color-base").trim().split(" ");const r=o.darken?o.darken:0,s=o.saturation?o.saturation:0,n=o["hue-rotate"]?o["hue-rotate"]:0,l=r>=0?1+r**2:1-r**2;o=s>=0?1+s**2:1-s**2,e=`hsl(${(parseInt(e[0])+n)%360}deg ${(parseInt(e[1])*o).toFixed(2)}% ${(parseInt(e[2])*l).toFixed(2)}%)`,document.querySelector("meta[name=theme-color]").setAttribute("content",e)}e&&(t.dataset.mode="true"==e?"light":"dark")}}();
|
||||
!function(){if("undefined"!=typeof localStorage){const e=localStorage.getItem("fcnLightmode"),t=document.documentElement;let a,o=localStorage.getItem("fcnSiteSettings");if(o&&(o=JSON.parse(o))&&null!==o&&"object"==typeof o){Object.entries(o).forEach((([e,r])=>{switch(e){case"minimal":t.classList.toggle("minimal",r);break;case"darken":a=r>=0?1+r**2:1-r**2,t.style.setProperty("--darken",`(${a} + var(--lightness-offset))`);break;case"saturation":case"font-lightness":case"font-saturation":a=r>=0?1+r**2:1-r**2,t.style.setProperty(`--${e}`,`(${a} + var(--${e}-offset))`);break;case"hue-rotate":a=Number.isInteger(o["hue-rotate"])?o["hue-rotate"]:0,t.style.setProperty("--hue-rotate",`(${a}deg + var(--hue-offset))`);break;default:t.classList.toggle(`no-${e}`,!r)}})),t.dataset.fontWeight=o["font-weight"]?o["font-weight"]:"default",t.dataset.theme=o["site-theme"]&&!t.dataset.forceChildTheme?o["site-theme"]:"default";let e=getComputedStyle(document.documentElement).getPropertyValue("--theme-color-base").trim().split(" ");const r=o.darken?o.darken:0,s=o.saturation?o.saturation:0,n=o["hue-rotate"]?o["hue-rotate"]:0,l=r>=0?1+r**2:1-r**2;o=s>=0?1+s**2:1-s**2,e=`hsl(${(parseInt(e[0])+n)%360}deg ${(parseInt(e[1])*o).toFixed(2)}% ${(parseInt(e[2])*l).toFixed(2)}%)`,document.querySelector("meta[name=theme-color]").setAttribute("content",e)}e&&(t.dataset.mode="true"==e?"light":"dark")}}();
|
2
js/reminders.min.js
vendored
2
js/reminders.min.js
vendored
@ -1 +1 @@
|
||||
var fcn_userRemindersTimeout,fcn_reminders;function fcn_initializeReminders(e){const t=e.detail.data.reminders;!1!==t&&(Array.isArray(t.data)&&0===t.data.length&&(t.data={}),fcn_reminders=t,fcn_updateRemindersView(),localStorage.removeItem("fcnBookshelfContent"))}function fcn_toggleReminder(e){const t=fcn_getUserData();if(fcn_reminders&&t.reminders){if(localStorage.removeItem("fcnBookshelfContent"),JSON.stringify(fcn_reminders.data[e])!==JSON.stringify(t.reminders.data[e]))return fcn_reminders=t.reminders,fcn_showNotification(fictioneer_tl.notification.remindersResynchronized),void fcn_updateRemindersView();fcn_reminders.data.hasOwnProperty(e)?delete fcn_reminders.data[e]:fcn_reminders.data[e]={story_id:parseInt(e),timestamp:Date.now()},t.reminders.data[e]=fcn_reminders.data[e],t.lastLoaded=0,fcn_setUserData(t),fcn_updateRemindersView(),clearTimeout(fcn_userRemindersTimeout),fcn_userRemindersTimeout=setTimeout((()=>{fcn_ajaxPost({action:"fictioneer_ajax_toggle_reminder",fcn_fast_ajax:1,story_id:e,set:fcn_reminders.data.hasOwnProperty(e)}).then((e=>{e.data.error&&fcn_showNotification(e.data.error,5,"warning")})).catch((e=>{429===e.status?fcn_showNotification(fictioneer_tl.notification.slowDown,3,"warning"):e.status&&e.statusText&&fcn_showNotification(`${e.status}: ${e.statusText}`,5,"warning")}))}),fictioneer_ajax.post_debounce_rate)}}function fcn_updateRemindersView(){const e=fcn_getUserData();fcn_reminders&&e.reminders&&(_$$(".button-read-later").forEach((e=>{e.classList.toggle("_remembered",fcn_reminders.data.hasOwnProperty(e.dataset.storyId))})),_$$(".card").forEach((e=>{e.classList.toggle("has-reminder",fcn_reminders?.data.hasOwnProperty(e.dataset.storyId))})))}document.addEventListener("fcnUserDataReady",(e=>{fcn_initializeReminders(e)})),_$$(".button-read-later").forEach((e=>{e.addEventListener("click",(e=>{fcn_toggleReminder(e.currentTarget.dataset.storyId)}))}));
|
||||
var fcn_userRemindersTimeout,fcn_reminders;function fcn_initializeReminders(e){const t=e.detail.data.reminders;!1!==t&&(Array.isArray(t.data)&&0===t.data.length&&(t.data={}),fcn_reminders=t,fcn_updateRemindersView(),localStorage.removeItem("fcnBookshelfContent"))}function fcn_toggleReminder(e){const t=fcn_getUserData();if(fcn_reminders&&t.reminders){if(localStorage.removeItem("fcnBookshelfContent"),JSON.stringify(fcn_reminders.data[e])!==JSON.stringify(t.reminders.data[e]))return fcn_reminders=t.reminders,fcn_showNotification(fictioneer_tl.notification.remindersResynchronized),void fcn_updateRemindersView();fcn_reminders.data[e]?delete fcn_reminders.data[e]:fcn_reminders.data[e]={story_id:parseInt(e),timestamp:Date.now()},t.reminders.data[e]=fcn_reminders.data[e],t.lastLoaded=0,fcn_setUserData(t),fcn_updateRemindersView(),clearTimeout(fcn_userRemindersTimeout),fcn_userRemindersTimeout=setTimeout((()=>{fcn_ajaxPost({action:"fictioneer_ajax_toggle_reminder",fcn_fast_ajax:1,story_id:e,set:!!fcn_reminders.data[e]}).then((e=>{e.data.error&&fcn_showNotification(e.data.error,5,"warning")})).catch((e=>{429===e.status?fcn_showNotification(fictioneer_tl.notification.slowDown,3,"warning"):e.status&&e.statusText&&fcn_showNotification(`${e.status}: ${e.statusText}`,5,"warning")}))}),fictioneer_ajax.post_debounce_rate)}}function fcn_updateRemindersView(){const e=fcn_getUserData();fcn_reminders&&e.reminders&&(_$$(".button-read-later").forEach((e=>{e.classList.toggle("_remembered",!!fcn_reminders.data[e.dataset.storyId])})),_$$(".card").forEach((e=>{e.classList.toggle("has-reminder",!!fcn_reminders.data[e.dataset.storyId])})))}document.addEventListener("fcnUserDataReady",(e=>{fcn_initializeReminders(e)})),_$$(".button-read-later").forEach((e=>{e.addEventListener("click",(e=>{fcn_toggleReminder(e.currentTarget.dataset.storyId)}))}));
|
2
js/story.min.js
vendored
2
js/story.min.js
vendored
@ -1 +1 @@
|
||||
var fcn_storyCommentPage=1,fcn_storySettings=fcn_getStorySettings();function fcn_getStorySettings(){let t=fcn_parseJSON(localStorage.getItem("fcnStorySettings"))??fcn_defaultStorySettings();return(!t.hasOwnProperty("timestamp")||t.timestamp<1674770712849)&&(t=fcn_defaultStorySettings(),t.timestamp=Date.now()),fcn_setStorySettings(t),t}function fcn_defaultStorySettings(){return{view:"list",order:"asc",timestamp:1674770712849}}function fcn_setStorySettings(t){"object"==typeof t&&(fcn_storySettings=t,localStorage.setItem("fcnStorySettings",JSON.stringify(t)))}function fcn_applyStorySettings(){"object"==typeof fcn_storySettings&&(_$$("[data-view]").forEach((t=>{t.dataset.view="grid"==fcn_storySettings.view?"grid":"list"})),_$$("[data-order]").forEach((t=>{t.dataset.order="desc"==fcn_storySettings.order?"desc":"asc"})))}function fcn_toggleStoryTab(t){const e=t.closest(".story");e.querySelectorAll(".story__tab-target._current, .story__tabs ._current").forEach((t=>{t.classList.remove("_current")})),e.querySelectorAll(`[data-finder="${t.dataset.target}"]`).forEach((t=>{t.classList.add("_current")})),e.querySelector(".story__tabs").dataset.current=t.dataset.target,t.classList.add("_current")}function fcn_loadStoryComments(t){let e;_$(".load-more-list-item").remove(),_$(".comments-loading-placeholder").classList.remove("hidden"),fcn_ajaxGet({post_id:t.dataset.storyId??fcn_inlineStorage.postId,page:fcn_storyCommentPage},"get_story_comments").then((t=>{t.success?(_$(".fictioneer-comments__list > ul").innerHTML+=t.data.html,fcn_storyCommentPage++):t.data?.error&&(e=fcn_buildErrorNotice(t.data.error))})).catch((t=>{e=fcn_buildErrorNotice(t)})).then((()=>{_$(".comments-loading-placeholder").remove(),e&&_$(".fictioneer-comments__list > ul").appendChild(e)}))}function fcn_startEpubDownload(t,e=0){e>3?t.classList.remove("ajax-in-progress"):fcn_ajaxGet({action:"fictioneer_ajax_download_epub",story_id:t.dataset.storyId}).then((r=>{r.success?(window.location.href=t.href,setTimeout((()=>{t.classList.remove("ajax-in-progress")}),2e3)):setTimeout((()=>{fcn_startEpubDownload(t,e+1)}),2e3)})).catch((e=>{t.classList.remove("ajax-in-progress"),e.status&&e.statusText&&fcn_showNotification(`${e.status}: ${e.statusText}`,5,"warning")}))}fcn_applyStorySettings(),_$$('[data-click-action*="toggle-chapter-order"]').forEach((t=>{t.addEventListener("click",(t=>{fcn_storySettings.order="asc"===t.currentTarget.dataset.order?"desc":"asc",fcn_setStorySettings(fcn_storySettings),fcn_applyStorySettings()}))})),_$$('[data-click-action*="toggle-chapter-view"]').forEach((t=>{t.addEventListener("click",(t=>{fcn_storySettings.view="list"===t.currentTarget.dataset.view?"grid":"list",fcn_setStorySettings(fcn_storySettings),fcn_applyStorySettings()}))})),_$$(".chapter-group__folding-toggle").forEach((t=>{t.addEventListener("click",(t=>{const e=t.currentTarget.closest(".chapter-group[data-folded]");e&&(e.dataset.folded="true"==e.dataset.folded?"false":"true")}))})),_$$(".tabs__item").forEach((t=>{t.addEventListener("click",(t=>{fcn_toggleStoryTab(t.currentTarget)}))})),_$(".comment-section")?.addEventListener("click",(t=>{t.target?.classList.contains("load-more-comments-button")&&fcn_loadStoryComments(t.target)})),_$$('[data-action="download-epub"]').forEach((t=>{t.addEventListener("click",(t=>{t.preventDefault(),t.currentTarget.classList.contains("ajax-in-progress")||(t.currentTarget.classList.add("ajax-in-progress"),fcn_startEpubDownload(t.currentTarget))}))}));
|
||||
var fcn_storyCommentPage=1,fcn_storySettings=fcn_getStorySettings();function fcn_getStorySettings(){let t=fcn_parseJSON(localStorage.getItem("fcnStorySettings"))??fcn_defaultStorySettings();return t.timestamp<1674770712849&&(t=fcn_defaultStorySettings(),t.timestamp=Date.now()),fcn_setStorySettings(t),t}function fcn_defaultStorySettings(){return{view:"list",order:"asc",timestamp:1674770712849}}function fcn_setStorySettings(t){"object"==typeof t&&(fcn_storySettings=t,localStorage.setItem("fcnStorySettings",JSON.stringify(t)))}function fcn_applyStorySettings(){"object"==typeof fcn_storySettings&&(_$$("[data-view]").forEach((t=>{t.dataset.view="grid"==fcn_storySettings.view?"grid":"list"})),_$$("[data-order]").forEach((t=>{t.dataset.order="desc"==fcn_storySettings.order?"desc":"asc"})))}function fcn_toggleStoryTab(t){const e=t.closest(".story");e.querySelectorAll(".story__tab-target._current, .story__tabs ._current").forEach((t=>{t.classList.remove("_current")})),e.querySelectorAll(`[data-finder="${t.dataset.target}"]`).forEach((t=>{t.classList.add("_current")})),e.querySelector(".story__tabs").dataset.current=t.dataset.target,t.classList.add("_current")}function fcn_loadStoryComments(t){let e;_$(".load-more-list-item").remove(),_$(".comments-loading-placeholder").classList.remove("hidden"),fcn_ajaxGet({post_id:t.dataset.storyId??fcn_inlineStorage.postId,page:fcn_storyCommentPage},"get_story_comments").then((t=>{t.success?(_$(".fictioneer-comments__list > ul").innerHTML+=t.data.html,fcn_storyCommentPage++):t.data?.error&&(e=fcn_buildErrorNotice(t.data.error))})).catch((t=>{e=fcn_buildErrorNotice(t)})).then((()=>{_$(".comments-loading-placeholder").remove(),e&&_$(".fictioneer-comments__list > ul").appendChild(e)}))}function fcn_startEpubDownload(t,e=0){e>3?t.classList.remove("ajax-in-progress"):fcn_ajaxGet({action:"fictioneer_ajax_download_epub",story_id:t.dataset.storyId}).then((r=>{r.success?(window.location.href=t.href,setTimeout((()=>{t.classList.remove("ajax-in-progress")}),2e3)):setTimeout((()=>{fcn_startEpubDownload(t,e+1)}),2e3)})).catch((e=>{t.classList.remove("ajax-in-progress"),e.status&&e.statusText&&fcn_showNotification(`${e.status}: ${e.statusText}`,5,"warning")}))}fcn_applyStorySettings(),_$$('[data-click-action*="toggle-chapter-order"]').forEach((t=>{t.addEventListener("click",(t=>{fcn_storySettings.order="asc"===t.currentTarget.dataset.order?"desc":"asc",fcn_setStorySettings(fcn_storySettings),fcn_applyStorySettings()}))})),_$$('[data-click-action*="toggle-chapter-view"]').forEach((t=>{t.addEventListener("click",(t=>{fcn_storySettings.view="list"===t.currentTarget.dataset.view?"grid":"list",fcn_setStorySettings(fcn_storySettings),fcn_applyStorySettings()}))})),_$$(".chapter-group__folding-toggle").forEach((t=>{t.addEventListener("click",(t=>{const e=t.currentTarget.closest(".chapter-group[data-folded]");e&&(e.dataset.folded="true"==e.dataset.folded?"false":"true")}))})),_$$(".tabs__item").forEach((t=>{t.addEventListener("click",(t=>{fcn_toggleStoryTab(t.currentTarget)}))})),_$(".comment-section")?.addEventListener("click",(t=>{t.target?.classList.contains("load-more-comments-button")&&fcn_loadStoryComments(t.target)})),_$$('[data-action="download-epub"]').forEach((t=>{t.addEventListener("click",(t=>{t.preventDefault(),t.currentTarget.classList.contains("ajax-in-progress")||(t.currentTarget.classList.add("ajax-in-progress"),fcn_startEpubDownload(t.currentTarget))}))}));
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
/**
|
||||
* Plugin Name: Fictioneer Fast Requests
|
||||
* Description: Skips plugins for faster requests.
|
||||
* Version: 1.0
|
||||
* Version: 1.1.0
|
||||
* Author: Tetrakern
|
||||
* Author URI: https://github.com/Tetrakern
|
||||
* Donate link: https://ko-fi.com/tetrakern
|
||||
@ -11,12 +11,7 @@
|
||||
*/
|
||||
|
||||
// Check if AJAX request
|
||||
if (
|
||||
( defined( 'DOING_AJAX' ) && DOING_AJAX ) &&
|
||||
isset( $_REQUEST['fcn_fast_ajax'] ) &&
|
||||
strpos( $_REQUEST['action'] ?? '', 'fictioneer_ajax' ) === 0 &&
|
||||
strpos( $_REQUEST['action'] ?? '', '_comment' ) === false
|
||||
) {
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_REQUEST['fcn_fast_ajax'] ) ) {
|
||||
add_filter( 'option_active_plugins', 'fictioneer_exclude_plugins' );
|
||||
}
|
||||
|
||||
@ -40,10 +35,10 @@ if ( strpos( $request_uri, 'wp-json/fictioneer/' ) !== false ) {
|
||||
function fictioneer_exclude_plugins( $plugins ) {
|
||||
// Setup
|
||||
$allow_list = array(
|
||||
'plugin-name/plugin-name.php' // Example!
|
||||
// 'plugin-name/plugin-name.php' // Example!
|
||||
);
|
||||
|
||||
// Remove not allowed plugins
|
||||
// Remove not allowed plugins, but allow all Fictioneer ones
|
||||
foreach ( $plugins as $index => $plugin ) {
|
||||
if ( ! in_array( $plugin, $allow_list ) && strpos( $plugin, 'fictioneer' ) === false ) {
|
||||
unset( $plugins[ $index ] );
|
||||
@ -57,9 +52,8 @@ function fictioneer_exclude_plugins( $plugins ) {
|
||||
// Check if AJAX comment request
|
||||
if (
|
||||
get_option( 'fictioneer_enable_fast_ajax_comments' ) &&
|
||||
( defined( 'DOING_AJAX' ) && DOING_AJAX ) &&
|
||||
strpos( $_REQUEST['action'] ?? '', 'fictioneer_ajax' ) === 0 &&
|
||||
strpos( $_REQUEST['action'] ?? '', '_comment' ) !== false
|
||||
defined( 'DOING_AJAX' ) && DOING_AJAX &&
|
||||
isset( $_REQUEST['fcn_fast_comment_ajax'] )
|
||||
) {
|
||||
add_filter( 'option_active_plugins', 'fictioneer_exclude_plugins_while_commenting' );
|
||||
}
|
||||
@ -93,5 +87,3 @@ function fictioneer_exclude_plugins_while_commenting( $plugins ) {
|
||||
// Filter and continue
|
||||
return array_intersect( $plugins, $allow_list );
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -5,9 +5,9 @@ Author URI: https://github.com/Tetrakern
|
||||
Donate link: [Support me on Ko-Fi](https://ko-fi.com/tetrakern)
|
||||
Contributors: tetrakern
|
||||
Requires at least: 6.1.0
|
||||
Tested up to: 6.5.2
|
||||
Tested up to: 6.5.3
|
||||
Requires PHP: 7.4
|
||||
Stable tag: 5.15.2
|
||||
Stable tag: 5.16.0
|
||||
License: GNU General Public License v3.0 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl.html
|
||||
|
||||
|
BIN
repo/assets/user_unlock_posts.jpg
Normal file
BIN
repo/assets/user_unlock_posts.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
130
src/js/admin.js
130
src/js/admin.js
@ -1069,3 +1069,133 @@ function fcn_addRelationship(source, destination) {
|
||||
// Disable
|
||||
source.classList.add('disabled');
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// UNLOCK POSTS
|
||||
// =============================================================================
|
||||
|
||||
var /** @type {timeoutID} */ fcn_unlockPostsTimer;
|
||||
|
||||
_$('[data-controller="fcn-unlock-posts"]')?.addEventListener('click', event => {
|
||||
// Evaluate clicks on the interface
|
||||
fcn_unlockPostsHandleClicks(event.target.closest('[data-target]'));
|
||||
});
|
||||
|
||||
_$('[data-target="fcn-unlock-posts-search"]')?.addEventListener('input', () => {
|
||||
// Clear previous timer (if any)
|
||||
clearTimeout(fcn_unlockPostsTimer);
|
||||
|
||||
// Trigger search after delay
|
||||
fcn_unlockPostsTimer = setTimeout(() => {
|
||||
fcn_unlockPostsSearch();
|
||||
}, 800);
|
||||
});
|
||||
|
||||
_$('[data-target="fcn-unlock-posts-select"]')?.addEventListener('input', () => {
|
||||
// Clear previous timer (if any)
|
||||
clearTimeout(fcn_unlockPostsTimer);
|
||||
|
||||
// Start search
|
||||
fcn_unlockPostsSearch();
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle clicks on the Unlock Posts interface.
|
||||
*
|
||||
* @since 5.16.0
|
||||
* @param {HTMLElement} target - The element that was clicked.
|
||||
*/
|
||||
|
||||
function fcn_unlockPostsHandleClicks(target) {
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delegate or perform action...
|
||||
switch (target.dataset.target) {
|
||||
case 'fcn-unlock-posts-delete':
|
||||
target.closest('[data-target="fcn-unlock-posts-item"').remove();
|
||||
break;
|
||||
case 'fcn-unlock-posts-search-item':
|
||||
fcn_unlockPostsAdd(target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search posts to unlock.
|
||||
*
|
||||
* @since 5.16.0
|
||||
*/
|
||||
|
||||
function fcn_unlockPostsSearch() {
|
||||
// Setup
|
||||
const container = _$('.unlock-posts');
|
||||
const search = _$('[data-target="fcn-unlock-posts-search"]');
|
||||
const results = _$('[data-target="fcn-unlock-posts-search-results"]');
|
||||
const selected = _$('[data-target="fcn-unlock-posts-selected"]');
|
||||
|
||||
// Abort if...
|
||||
if (!container || !search || (!search.value && !_$('[data-target="fcn-unlock-posts-search-item"]'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Payload
|
||||
const payload = {
|
||||
'action': 'fictioneer_ajax_search_posts_to_unlock',
|
||||
'search': search.value,
|
||||
'type': _$('[data-target="fcn-unlock-posts-select"]')?.value || 'any',
|
||||
'nonce': container.querySelector('[name="unlock_posts_nonce"]').value
|
||||
};
|
||||
|
||||
// Indicate process
|
||||
container.classList.add('ajax-in-progress');
|
||||
|
||||
// Request
|
||||
fcn_ajaxPost(payload)
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
results.innerHTML = response.data.html;
|
||||
} else {
|
||||
results.innerHTML = response.data.error;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
results.innerHTML = error;
|
||||
})
|
||||
.then(() => {
|
||||
container.classList.remove('ajax-in-progress');
|
||||
|
||||
results.querySelectorAll('[data-target="fcn-unlock-posts-search-item"]').forEach(item => {
|
||||
if (selected.querySelector(`[data-post-id="${item.dataset.postId}"]`)) {
|
||||
item.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add post items to the Unlock Posts selection.
|
||||
*
|
||||
* @since 5.16.0
|
||||
* @param {HTMLElement} target - The element that was clicked.
|
||||
*/
|
||||
|
||||
function fcn_unlockPostsAdd(target) {
|
||||
// Setup
|
||||
const template = _$('[data-target="fcn-unlock-posts-item-template"]').content.cloneNode(true);
|
||||
const item = template.querySelector('.unlock-posts__item');
|
||||
|
||||
// Build node
|
||||
item.dataset.postId = target.dataset.postId;
|
||||
item.title = target.title;
|
||||
item.querySelector('input[type="hidden"]').value = target.dataset.postId;
|
||||
item.querySelector('.unlock-posts__item-title').innerText = target.querySelector('.unlock-posts__item-title').innerText;
|
||||
item.querySelector('.unlock-posts__item-meta').innerText = target.querySelector('.unlock-posts__item-meta').innerText;
|
||||
|
||||
// Append
|
||||
_$('[data-target="fcn-unlock-posts-selected"]').appendChild(template);
|
||||
|
||||
// Remove search node
|
||||
target.remove();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ function fcn_updateBookshelfView(action = null, page = null, order = null, scrol
|
||||
|
||||
// Storage item valid for 60 seconds
|
||||
if (
|
||||
! storage.hasOwnProperty('timestamp') ||
|
||||
! storage['timestamp'] ||
|
||||
storage['timestamp'] + 60000 < Date.now()
|
||||
) {
|
||||
localStorage.removeItem('fcnBookshelfContent');
|
||||
@ -67,10 +67,7 @@ function fcn_updateBookshelfView(action = null, page = null, order = null, scrol
|
||||
}
|
||||
|
||||
// Check if content already cached
|
||||
if (
|
||||
storage.hasOwnProperty('html') &&
|
||||
storage['html'].hasOwnProperty(htmlKey)
|
||||
) {
|
||||
if (storage['html'] && storage['html'][htmlKey]) {
|
||||
fcn_bookshelfTarget.innerHTML = storage['html'][htmlKey];
|
||||
fcn_bookshelfTarget.classList.remove('ajax-in-progress');
|
||||
fcn_bookshelfTarget.dataset.page = page;
|
||||
|
@ -68,7 +68,8 @@ function fcn_getCommentSection(post_id = null, page = null, order = null, scroll
|
||||
'action': 'fictioneer_ajax_get_comment_section',
|
||||
'post_id': post_id ?? fcn_commentSection.dataset.postId,
|
||||
'page': parseInt(page),
|
||||
'corder': order
|
||||
'corder': order,
|
||||
'fcn_fast_comment_ajax': 1
|
||||
};
|
||||
|
||||
if (fcn_urlParams.commentcode) {
|
||||
|
@ -1263,7 +1263,7 @@ function fcn_updateSiteTheme(theme) {
|
||||
|
||||
_$$('.site-setting-site-theme').forEach(element => {
|
||||
// Initialize site theme select elements
|
||||
element.value = fcn_siteSettings.hasOwnProperty('site-theme') ? fcn_siteSettings['site-theme'] : 'default';
|
||||
element.value = fcn_siteSettings['site-theme'] ? fcn_siteSettings['site-theme'] : 'default';
|
||||
|
||||
// Modified?
|
||||
_$$$('site-setting-theme-reset').classList.toggle('_modified', element.value != 'default');
|
||||
|
@ -319,7 +319,7 @@ function fcn_getFormatting() {
|
||||
}
|
||||
|
||||
// Timestamp allows to force resets after script updates (may annoy users)
|
||||
if (!formatting.hasOwnProperty('timestamp') || formatting['timestamp'] < 1651164557584) {
|
||||
if (formatting['timestamp'] < 1651164557584) {
|
||||
formatting = fcn_defaultFormatting();
|
||||
formatting['timestamp'] = Date.now();
|
||||
}
|
||||
|
@ -97,11 +97,11 @@ function fcn_toggleCheckmark(storyId, type, chapter = null, source = null, mode
|
||||
}
|
||||
|
||||
// Initialize if story is not yet tracked
|
||||
if (!fcn_checkmarks.data.hasOwnProperty(storyId)) {
|
||||
if (!fcn_checkmarks.data[storyId]) {
|
||||
fcn_checkmarks.data[storyId] = [];
|
||||
}
|
||||
|
||||
if (!currentUserData.checkmarks.data.hasOwnProperty(storyId)) {
|
||||
if (!currentUserData.checkmarks.data[storyId]) {
|
||||
currentUserData.checkmarks.data[storyId] = [];
|
||||
}
|
||||
|
||||
@ -262,8 +262,7 @@ function fcn_updateCheckmarksView() {
|
||||
const storyId = parseInt(fcn_inlineStorage.storyId);
|
||||
|
||||
if (storyId) {
|
||||
const completed = checkmarks.data.hasOwnProperty(storyId) &&
|
||||
checkmarks.data[storyId].includes(storyId);
|
||||
const completed = checkmarks.data[storyId] && checkmarks.data[storyId].includes(storyId);
|
||||
|
||||
// Add missing checkmarks
|
||||
if (completed) {
|
||||
@ -293,7 +292,7 @@ function fcn_updateCheckmarksView() {
|
||||
_$$('button.checkmark').forEach(button => {
|
||||
const checkStoryId = parseInt(button.dataset.storyId);
|
||||
|
||||
if (checkmarks.data.hasOwnProperty(checkStoryId)) {
|
||||
if (checkmarks.data[checkStoryId]) {
|
||||
const checked = checkmarks.data[checkStoryId].includes(parseInt(button.dataset.id));
|
||||
|
||||
button.classList.toggle('marked', checked);
|
||||
@ -304,7 +303,7 @@ function fcn_updateCheckmarksView() {
|
||||
// Update icon and buttons on cards
|
||||
_$$('.card').forEach(card => {
|
||||
const cardStoryId = parseInt(card.dataset.storyId);
|
||||
const force = checkmarks.data.hasOwnProperty(cardStoryId) &&
|
||||
const force = checkmarks.data[cardStoryId] &&
|
||||
(
|
||||
checkmarks.data[cardStoryId].includes(parseInt(card.dataset.checkId)) ||
|
||||
checkmarks.data[cardStoryId].includes(cardStoryId)
|
||||
|
@ -77,7 +77,8 @@ function fcn_moderateComment(id, operation) {
|
||||
fcn_ajaxPost({
|
||||
'action': 'fictioneer_ajax_moderate_comment',
|
||||
'operation': operation,
|
||||
'id': id
|
||||
'id': id,
|
||||
'fcn_fast_comment_ajax': 1
|
||||
})
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
@ -194,7 +195,8 @@ function fcn_flagComment(source) {
|
||||
fcn_ajaxPost({
|
||||
'action': 'fictioneer_ajax_report_comment',
|
||||
'id': comment.dataset.id,
|
||||
'dubious': reportButton.classList.contains('_dubious')
|
||||
'dubious': reportButton.classList.contains('_dubious'),
|
||||
'fcn_fast_comment_ajax': 1
|
||||
})
|
||||
.then(response => {
|
||||
// Comment successfully reported?
|
||||
@ -420,7 +422,8 @@ function fcn_bindAJAXCommentSubmit() {
|
||||
'privacy_consent': privacy_consent?.checked ?? 0,
|
||||
'unfiltered_html': _$$$('_wp_unfiltered_html_comment_disabled')?.value ?? '',
|
||||
'depth': parent ? parseInt(parent.dataset.depth) + 1 : 1,
|
||||
'fictioneer_comment_validator': jsValidator?.value ?? 0
|
||||
'fictioneer_comment_validator': jsValidator?.value ?? 0,
|
||||
'fcn_fast_comment_ajax': 1
|
||||
};
|
||||
|
||||
// Optional payload
|
||||
@ -647,7 +650,8 @@ function fcn_submitInlineCommentEdit(source) {
|
||||
fcn_ajaxPost({
|
||||
'action': 'fictioneer_ajax_edit_comment',
|
||||
'comment_id': red.id.replace('comment-', ''),
|
||||
'content': content
|
||||
'content': content,
|
||||
'fcn_fast_comment_ajax': 1
|
||||
})
|
||||
.then(response => {
|
||||
// Comment successfully updated?
|
||||
@ -843,7 +847,8 @@ function fcn_deleteMyComment(button) {
|
||||
// Request
|
||||
fcn_ajaxPost({
|
||||
'action': 'fictioneer_ajax_delete_my_comment',
|
||||
'comment_id': comment.dataset.id
|
||||
'comment_id': comment.dataset.id,
|
||||
'fcn_fast_comment_ajax': 1
|
||||
})
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
@ -919,7 +924,8 @@ function fcn_getCommentForm() {
|
||||
// Request
|
||||
fcn_ajaxGet({
|
||||
'action': 'fictioneer_ajax_get_comment_form',
|
||||
'post_id': _$$$('comments').dataset.postId
|
||||
'post_id': _$$$('comments').dataset.postId,
|
||||
'fcn_fast_comment_ajax': 1
|
||||
})
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
|
@ -8,7 +8,7 @@ diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesT
|
||||
diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=2*f,h=Array(g),l=Array(g),k=0;k<g;k++)h[k]=-1,l[k]=-1;h[f+1]=0;l[f+1]=0;k=d-e;for(var m=0!=k%2,p=0,x=0,w=0,q=0,t=0;t<f&&!((new Date).getTime()>c);t++){for(var v=-t+p;v<=t-x;v+=2){var n=f+v;var r=v==-t||v!=t&&h[n-1]<h[n+1]?h[n+1]:h[n-1]+1;for(var y=r-v;r<d&&y<e&&a.charAt(r)==b.charAt(y);)r++,y++;h[n]=r;if(r>d)x+=2;else if(y>e)p+=2;else if(m&&(n=f+k-v,0<=n&&n<g&&-1!=l[n])){var u=d-l[n];if(r>=
|
||||
u)return this.diff_bisectSplit_(a,b,r,y,c)}}for(v=-t+w;v<=t-q;v+=2){n=f+v;u=v==-t||v!=t&&l[n-1]<l[n+1]?l[n+1]:l[n-1]+1;for(r=u-v;u<d&&r<e&&a.charAt(d-u-1)==b.charAt(e-r-1);)u++,r++;l[n]=u;if(u>d)q+=2;else if(r>e)w+=2;else if(!m&&(n=f+k-v,0<=n&&n<g&&-1!=h[n]&&(r=h[n],y=f+r-n,u=d-u,r>=u)))return this.diff_bisectSplit_(a,b,r,y,c)}}return[new diff_match_patch.Diff(DIFF_DELETE,a),new diff_match_patch.Diff(DIFF_INSERT,b)]};
|
||||
diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};
|
||||
diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,g=-1,h=d.length;g<a.length-1;){g=a.indexOf("\n",c);-1==g&&(g=a.length-1);var l=a.substring(c,g+1);(e.hasOwnProperty?e.hasOwnProperty(l):void 0!==e[l])?b+=String.fromCharCode(e[l]):(h==f&&(l=a.substring(c),g=a.length),b+=String.fromCharCode(h),e[l]=h,d[h++]=l);c=g+1}return b}var d=[],e={};d[0]="";var f=4E4,g=c(a);f=65535;var h=c(b);return{chars1:g,chars2:h,lineArray:d}};
|
||||
diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,g=-1,h=d.length;g<a.length-1;){g=a.indexOf("\n",c);-1==g&&(g=a.length-1);var l=a.substring(c,g+1);(void 0 !== e[l])?b+=String.fromCharCode(e[l]):(h==f&&(l=a.substring(c),g=a.length),b+=String.fromCharCode(h),e[l]=h,d[h++]=l);c=g+1}return b}var d=[],e={};d[0]="";var f=4E4,g=c(a);f=65535;var h=c(b);return{chars1:g,chars2:h,lineArray:d}};
|
||||
diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
|
||||
diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
|
||||
diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;d=0;for(var e=1;;){var f=a.substring(c-e);f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};
|
||||
|
@ -82,7 +82,7 @@ function fcn_toggleFollow(storyId) {
|
||||
}
|
||||
|
||||
// Set/Unset follow
|
||||
if (fcn_follows.data.hasOwnProperty(storyId)) {
|
||||
if (fcn_follows.data[storyId]) {
|
||||
delete fcn_follows.data[storyId];
|
||||
} else {
|
||||
fcn_follows.data[storyId] = { 'story_id': parseInt(storyId), 'timestamp': Date.now() };
|
||||
@ -105,7 +105,7 @@ function fcn_toggleFollow(storyId) {
|
||||
'action': 'fictioneer_ajax_toggle_follow',
|
||||
'fcn_fast_ajax': 1,
|
||||
'story_id': storyId,
|
||||
'set': fcn_follows.data.hasOwnProperty(storyId)
|
||||
'set': fcn_follows.data[storyId] ? true : false // This must be this verbose!
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data.error) {
|
||||
@ -144,7 +144,7 @@ function fcn_updateFollowsView() {
|
||||
_$$('.button-follow-story').forEach(element => {
|
||||
element.classList.toggle(
|
||||
'_followed',
|
||||
fcn_follows?.data.hasOwnProperty(element.dataset.storyId)
|
||||
fcn_follows?.data[element.dataset.storyId] ? true : false
|
||||
);
|
||||
});
|
||||
|
||||
@ -152,7 +152,7 @@ function fcn_updateFollowsView() {
|
||||
_$$('.card').forEach(element => {
|
||||
element.classList.toggle(
|
||||
'has-follow',
|
||||
fcn_follows?.data.hasOwnProperty(element.dataset.storyId)
|
||||
fcn_follows?.data[element.dataset.storyId] ? true : false
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -31,8 +31,8 @@
|
||||
}
|
||||
});
|
||||
|
||||
root.dataset.fontWeight = settings.hasOwnProperty('font-weight') ? settings['font-weight'] : 'default';
|
||||
root.dataset.theme = settings.hasOwnProperty('site-theme') && ! root.dataset.forceChildTheme ? settings['site-theme'] : 'default';
|
||||
root.dataset.fontWeight = settings['font-weight'] ? settings['font-weight'] : 'default';
|
||||
root.dataset.theme = (settings['site-theme'] && !root.dataset.forceChildTheme) ? settings['site-theme'] : 'default';
|
||||
|
||||
let themeColor = getComputedStyle(document.documentElement).getPropertyValue('--theme-color-base').trim().split(' ');
|
||||
|
||||
|
@ -80,7 +80,7 @@ function fcn_toggleReminder(storyId) {
|
||||
}
|
||||
|
||||
// Set/Unset reminder
|
||||
if (fcn_reminders.data.hasOwnProperty(storyId)) {
|
||||
if (fcn_reminders.data[storyId]) {
|
||||
delete fcn_reminders.data[storyId];
|
||||
} else {
|
||||
fcn_reminders.data[storyId] = { 'story_id': parseInt(storyId), 'timestamp': Date.now() };
|
||||
@ -103,7 +103,7 @@ function fcn_toggleReminder(storyId) {
|
||||
'action': 'fictioneer_ajax_toggle_reminder',
|
||||
'fcn_fast_ajax': 1,
|
||||
'story_id': storyId,
|
||||
'set': fcn_reminders.data.hasOwnProperty(storyId)
|
||||
'set': fcn_reminders.data[storyId] ? true : false // This must be this verbose!
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data.error) {
|
||||
@ -142,7 +142,7 @@ function fcn_updateRemindersView() {
|
||||
_$$('.button-read-later').forEach(element => {
|
||||
element.classList.toggle(
|
||||
'_remembered',
|
||||
fcn_reminders.data.hasOwnProperty(element.dataset.storyId)
|
||||
fcn_reminders.data[element.dataset.storyId] ? true : false
|
||||
);
|
||||
});
|
||||
|
||||
@ -150,7 +150,7 @@ function fcn_updateRemindersView() {
|
||||
_$$('.card').forEach(element => {
|
||||
element.classList.toggle(
|
||||
'has-reminder',
|
||||
fcn_reminders?.data.hasOwnProperty(element.dataset.storyId)
|
||||
fcn_reminders.data[element.dataset.storyId] ? true : false
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ function fcn_getStorySettings() {
|
||||
let settings = fcn_parseJSON(localStorage.getItem('fcnStorySettings')) ?? fcn_defaultStorySettings();
|
||||
|
||||
// Timestamp allows to force resets after script updates (may annoy users)
|
||||
if (!settings.hasOwnProperty('timestamp') || settings['timestamp'] < 1674770712849) {
|
||||
if (settings['timestamp'] < 1674770712849) {
|
||||
settings = fcn_defaultStorySettings();
|
||||
settings['timestamp'] = Date.now();
|
||||
}
|
||||
|
@ -211,7 +211,7 @@
|
||||
font-weight: var(--font-weight-strong);
|
||||
text-align: center;
|
||||
padding: 1rem 0;
|
||||
margin-top: 2rem;
|
||||
margin-top: 3rem;
|
||||
|
||||
&-message {
|
||||
text-transform: uppercase;
|
||||
|
@ -70,7 +70,7 @@
|
||||
|
||||
.main-navigation {
|
||||
&.is-sticky {
|
||||
:is(.icon-menu__item, .icon-menu__item.follow-menu-item) {
|
||||
.menu-item {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
@ -1012,3 +1012,72 @@ td.comment {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.unlock-posts {
|
||||
&__unlocked-posts,
|
||||
&__search-results {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
|
||||
&:not(:empty) {
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
&__search-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px 5px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
cursor: default;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
background: #ddd;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
padding-left: 9px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
|
||||
&:hover {
|
||||
background: #d6d6d6;
|
||||
}
|
||||
|
||||
&._searched {
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
padding: 7px;
|
||||
border: 1px dashed #ccc;
|
||||
|
||||
&:hover {
|
||||
background: rgb(0 0 0 / 3%);
|
||||
}
|
||||
}
|
||||
|
||||
> span:first-of-type {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 160px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&__delete {
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
background: transparent;
|
||||
padding: 4px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
&:not(.ajax-in-progress) .fa-spinner {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
@use 'sass:math';
|
||||
|
||||
$block-spacing: 32px;
|
||||
|
||||
// =============================================================================
|
||||
@ -258,7 +260,7 @@ span.underline {
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 28px;
|
||||
margin: $block-spacing / 2 0;
|
||||
margin: math.div($block-spacing, 2) 0;
|
||||
|
||||
ul,
|
||||
ol {
|
||||
|
@ -9,9 +9,9 @@ License: GNU General Public License v3.0 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl.html
|
||||
|
||||
Requires at least: 6.1.0
|
||||
Tested up to: 6.5.2
|
||||
Tested up to: 6.5.3
|
||||
Requires PHP: 7.4
|
||||
Version: 5.15.2
|
||||
Version: 5.16.0
|
||||
Text Domain: fictioneer
|
||||
|
||||
Description: Standalone solution for publishing and reading web fictions.
|
||||
|
Loading…
x
Reference in New Issue
Block a user