0675c9f7d8
The v0.1.1 wink was rendered as a static SVG (left eye drawn as a closed curve). Once the 5% random gate picked the wink tone, the left eye stayed closed until the next page render — if the dashboard sat idle, Buddy was stuck mid-wink indefinitely. David's report: "the eye does not unblink." v0.1.2's lower probability (30% → 5%) reduced how often you'd see the stuck state, but didn't fix the underlying issue. This release makes the wink a real transient animation: - sprite.php no longer swaps the left eye for a closed path when tone is wink — both eyes are always open circles in the SVG - buddy.css adds @keyframes buddyWink that briefly closes the left eye (scaleY 0.1) for ~250ms every 2.5s, applied only when the parent has the .buddy-sprite--wink class - right eye keeps its normal 5s blink — the asymmetry is what makes it read as a wink rather than a synchronised blink - mouth/cheeks/label still differ for wink tone (those are valid static state changes); only the eye behaviour moved to animation Net effect: when the 5% chance fires, Buddy now actually winks (closes, opens, closes, opens) instead of freezing one-eye-shut.
122 lines
4.3 KiB
PHP
122 lines
4.3 KiB
PHP
<?php
|
|
/**
|
|
* Buddy — a friendly pet for your WordPress dashboard
|
|
*
|
|
* Plugin Name: Buddy
|
|
* Plugin URI: https://icanhelp.ie/buddy
|
|
* Description: Adopt a small companion that lives in your WordPress dashboard. Its mood reflects your site's health — published posts feed it, outdated plugins make it sick, clearing spam makes it happy. Gamifies WordPress maintenance with a bit of charm.
|
|
* Version: 0.1.3
|
|
* Requires at least: 5.0
|
|
* Requires PHP: 7.4
|
|
* Author: David Keane
|
|
* Author URI: https://rangersmyth.xyz/
|
|
* License: GPL v2 or later
|
|
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
|
* Text Domain: buddy
|
|
*
|
|
* @package Buddy
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) { exit; }
|
|
|
|
// Plugin coordinates.
|
|
if ( ! defined( 'BUDDY_VERSION' ) ) { define( 'BUDDY_VERSION', '0.1.3' ); }
|
|
if ( ! defined( 'BUDDY_FILE' ) ) { define( 'BUDDY_FILE', __FILE__ ); }
|
|
if ( ! defined( 'BUDDY_PATH' ) ) { define( 'BUDDY_PATH', plugin_dir_path( __FILE__ ) ); }
|
|
if ( ! defined( 'BUDDY_URL' ) ) { define( 'BUDDY_URL', plugin_dir_url( __FILE__ ) ); }
|
|
if ( ! defined( 'BUDDY_BASENAME' ) ) { define( 'BUDDY_BASENAME', plugin_basename( __FILE__ ) ); }
|
|
|
|
// Includes — each file owns one concern.
|
|
require_once BUDDY_PATH . 'inc/state.php'; // user_meta storage + stat helpers
|
|
require_once BUDDY_PATH . 'inc/sprite.php'; // inline-SVG character renderer
|
|
require_once BUDDY_PATH . 'inc/dashboard-widget.php'; // the pet on WP Dashboard
|
|
require_once BUDDY_PATH . 'inc/admin-page.php'; // dedicated Buddy admin page
|
|
require_once BUDDY_PATH . 'inc/about.php'; // About page
|
|
require_once BUDDY_PATH . 'inc/settings.php'; // Settings page
|
|
require_once BUDDY_PATH . 'inc/updater.php'; // self-hosted update checker against Gitea
|
|
|
|
/**
|
|
* Admin menu registration. Buddy gets its own top-level menu — the pet
|
|
* is a discrete enough thing to deserve a sidebar entry rather than
|
|
* being buried under Tools or Settings. Icon is dashicons-pets for the
|
|
* literal-match-to-purpose vibe (paw print).
|
|
*/
|
|
add_action( 'admin_menu', 'buddy_register_admin_menu' );
|
|
function buddy_register_admin_menu() {
|
|
add_menu_page(
|
|
__( 'Buddy', 'buddy' ),
|
|
__( 'Buddy', 'buddy' ),
|
|
'read', // any logged-in user with read access can see their own pet
|
|
'buddy',
|
|
'buddy_render_main_page',
|
|
'dashicons-pets',
|
|
72 // sits below Comments, above plugin entries
|
|
);
|
|
|
|
// "My Buddy" — main landing submenu. Same slug as parent so clicking
|
|
// either entry lands on the same page. Empty callback so only the
|
|
// parent's renderer fires (lesson learned from Logbook's duplicate-
|
|
// form bug).
|
|
add_submenu_page(
|
|
'buddy',
|
|
__( 'My Buddy', 'buddy' ),
|
|
__( 'My Buddy', 'buddy' ),
|
|
'read',
|
|
'buddy',
|
|
''
|
|
);
|
|
|
|
add_submenu_page(
|
|
'buddy',
|
|
__( 'Settings', 'buddy' ),
|
|
__( 'Settings', 'buddy' ),
|
|
'manage_options',
|
|
'buddy-settings',
|
|
'buddy_render_settings_page'
|
|
);
|
|
|
|
add_submenu_page(
|
|
'buddy',
|
|
__( 'About', 'buddy' ),
|
|
__( 'About', 'buddy' ),
|
|
'read',
|
|
'buddy-about',
|
|
'buddy_render_about_page'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Enqueue Buddy's CSS + JS on its own admin pages and on the main
|
|
* dashboard (where the widget lives).
|
|
*/
|
|
add_action( 'admin_enqueue_scripts', 'buddy_enqueue_admin_assets' );
|
|
function buddy_enqueue_admin_assets( $hook ) {
|
|
$buddy_hooks = array(
|
|
'index.php', // WP Dashboard (the widget lives here)
|
|
'toplevel_page_buddy', // Buddy main page
|
|
'buddy_page_buddy-settings', // Settings
|
|
'buddy_page_buddy-about', // About
|
|
);
|
|
if ( ! in_array( $hook, $buddy_hooks, true ) ) { return; }
|
|
|
|
wp_enqueue_style(
|
|
'buddy-admin',
|
|
BUDDY_URL . 'assets/css/buddy.css',
|
|
array(),
|
|
BUDDY_VERSION
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Activation hook: ensure the version option is set so the updater can
|
|
* track it.
|
|
*/
|
|
register_activation_hook( __FILE__, 'buddy_on_activate' );
|
|
function buddy_on_activate() {
|
|
if ( false === get_option( 'buddy_version' ) ) {
|
|
add_option( 'buddy_version', BUDDY_VERSION );
|
|
} else {
|
|
update_option( 'buddy_version', BUDDY_VERSION );
|
|
}
|
|
}
|