updated plugin `AudioIgniter` version 2.0.0

This commit is contained in:
KawaiiPunk 2023-06-05 11:21:12 +00:00 committed by Gitium
parent 1c5b451d2f
commit e5482aabb7
36 changed files with 776 additions and 242 deletions

View File

@ -62,7 +62,7 @@
vertical-align: middle; vertical-align: middle;
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
-webkit-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
border-radius: 2px; border-radius: 2px;
width: auto; width: auto;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,44 @@
/* General */
.ai-settings-box {
background-color: #ffffff;
padding: 25px;
border: 1px solid #D8D8D8;
box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.04);
}
.ai-settings-box > :last-child {
margin-bottom: 0;
}
/* Header / Nav */
.ai-settings-main-content-nav-header {
margin: 15px 0 40px;
display: flex;
align-items: center;
}
.ai-settings-main-content-nav {
display: flex;
grid-gap: 20px;
}
.ai-settings-main-content-nav-link {
color: #646970;
text-decoration: none;
font-size: 16px;
}
.ai-settings-main-content-nav-link.is-active {
font-weight: 700;
}
.ai-settings-main-content-nav-link.is-active,
.ai-settings-main-content-nav-link:hover {
color: #1D2327;
}
.ai-settings-main-content-nav-filters {
margin-left: auto;
}

View File

@ -0,0 +1 @@
.ai-settings-box{background-color:#fff;padding:25px;border:1px solid #d8d8d8;box-shadow:0 2px 0 rgba(0,0,0,.04)}.ai-settings-box>:last-child{margin-bottom:0}.ai-settings-main-content-nav-header{margin:15px 0 40px;display:flex;align-items:center}.ai-settings-main-content-nav{display:flex;grid-gap:20px}.ai-settings-main-content-nav-link{color:#646970;text-decoration:none;font-size:16px}.ai-settings-main-content-nav-link.is-active{font-weight:700}.ai-settings-main-content-nav-link.is-active,.ai-settings-main-content-nav-link:hover{color:#1d2327}.ai-settings-main-content-nav-filters{margin-left:auto}

View File

@ -0,0 +1,48 @@
$box-shadow-base: 0px 2px 0px rgba(0, 0, 0, 0.04);
$border-color-base: #D8D8D8;
$text-color-base: #646970;
$text-color-dark: #1D2327;
$background-color: #f2f2f2;
/* General */
.ai-settings-box {
background-color: #ffffff;
padding: 25px;
border: 1px solid $border-color-base;
box-shadow: $box-shadow-base;
> :last-child {
margin-bottom: 0;
}
}
/* Header / Nav */
.ai-settings-main-content-nav-header {
margin: 15px 0 40px;
display: flex;
align-items: center;
}
.ai-settings-main-content-nav {
display: flex;
grid-gap: 20px;
}
.ai-settings-main-content-nav-link {
color: $text-color-base;
text-decoration: none;
font-size: 16px;
&.is-active {
font-weight: 700;
}
&.is-active,
&:hover {
color: $text-color-dark;
}
}
.ai-settings-main-content-nav-filters {
margin-left: auto;
}

View File

@ -5,7 +5,7 @@
* Description: AudioIgniter lets you create music playlists and embed them in your WordPress posts, pages or custom post types and serve your audio content in style! * Description: AudioIgniter lets you create music playlists and embed them in your WordPress posts, pages or custom post types and serve your audio content in style!
* Author: The CSSIgniter Team * Author: The CSSIgniter Team
* Author URI: https://www.cssigniter.com * Author URI: https://www.cssigniter.com
* Version: 1.9.0 * Version: 2.0.0
* Text Domain: audioigniter * Text Domain: audioigniter
* Domain Path: languages * Domain Path: languages
* *
@ -131,9 +131,14 @@ class AudioIgniter {
load_plugin_textdomain( 'audioigniter', false, dirname( self::plugin_basename() ) . '/languages' ); load_plugin_textdomain( 'audioigniter', false, dirname( self::plugin_basename() ) . '/languages' );
require_once 'class-audioigniter-sanitizer.php'; require_once untrailingslashit( $this->plugin_path() ) . '/inc/class-audioigniter-sanitizer.php';
$this->sanitizer = new AudioIgniter_Sanitizer(); $this->sanitizer = new AudioIgniter_Sanitizer();
// if ( ! class_exists( 'AudioIgniter_Pro', false ) ) {
// require_once untrailingslashit( $this->plugin_path() ) . '/inc/class-audioigniter-admin-page-upsell.php';
// new AudioIgniter_Admin_Page_Upsell();
// }
// Initialization needed in every request. // Initialization needed in every request.
$this->init(); $this->init();
@ -205,11 +210,8 @@ class AudioIgniter {
* @since 1.0.0 * @since 1.0.0
*/ */
public function register_scripts() { public function register_scripts() {
wp_register_style( 'audioigniter', $this->plugin_url() . 'player/build/style.css', array(), $this->version ); wp_register_style( 'audioigniter', untrailingslashit( $this->plugin_url() ) . '/player/build/style.css', array(), $this->version );
wp_register_style( 'audioigniter-admin', $this->plugin_url() . 'assets/css/admin-styles.css', array(), $this->version ); wp_register_script( 'audioigniter', untrailingslashit( $this->plugin_url() ) . '/player/build/app.js', array(), $this->version, true );
wp_register_script( 'audioigniter', $this->plugin_url() . 'player/build/app.js', array(), $this->version, true );
wp_register_script( 'audioigniter-admin', $this->plugin_url() . 'assets/js/audioigniter.js', array(), $this->version, true );
wp_localize_script( 'audioigniter', 'aiStrings', apply_filters( 'audioigniter_aiStrings', array( wp_localize_script( 'audioigniter', 'aiStrings', apply_filters( 'audioigniter_aiStrings', array(
/* translators: %s is the track's title. */ /* translators: %s is the track's title. */
@ -232,6 +234,14 @@ class AudioIgniter {
'shuffle' => esc_html__( 'Shuffle', 'audioigniter' ), 'shuffle' => esc_html__( 'Shuffle', 'audioigniter' ),
) ) ); ) ) );
wp_localize_script( 'audioigniter', 'aiStats', array(
'enabled' => get_option( 'audioigniter_stats_enabled' ) && class_exists( 'AudioIgniter_Pro' ),
'apiUrl' => get_rest_url( null, 'audioigniter/v1' ),
) );
wp_register_style( 'audioigniter-admin', untrailingslashit( $this->plugin_url() ) . '/assets/css/admin-styles.css', array(), $this->version );
wp_register_script( 'audioigniter-admin', untrailingslashit( $this->plugin_url() ) . '/assets/js/audioigniter.js', array(), $this->version, true );
wp_localize_script( 'audioigniter-admin', 'ai_scripts', array( wp_localize_script( 'audioigniter-admin', 'ai_scripts', array(
'messages' => array( 'messages' => array(
'confirm_clear_tracks' => esc_html__( 'Do you really want to remove all tracks? (This will not delete your audio files).', 'audioigniter' ), 'confirm_clear_tracks' => esc_html__( 'Do you really want to remove all tracks? (This will not delete your audio files).', 'audioigniter' ),
@ -239,6 +249,8 @@ class AudioIgniter {
'media_title_upload_cover' => esc_html__( 'Select a cover image', 'audioigniter' ), 'media_title_upload_cover' => esc_html__( 'Select a cover image', 'audioigniter' ),
), ),
) ); ) );
wp_register_style( 'audioigniter-admin-settings', untrailingslashit( $this->plugin_url() ) . '/assets/css/admin/settings.css', array(), $this->version );
} }
/** /**
@ -264,6 +276,10 @@ class AudioIgniter {
wp_enqueue_style( 'audioigniter-admin' ); wp_enqueue_style( 'audioigniter-admin' );
wp_enqueue_script( 'audioigniter-admin' ); wp_enqueue_script( 'audioigniter-admin' );
} }
// if ( 'ai_playlist_page_audioigniter-upsell' === $screen->id ) {
// wp_enqueue_style( 'audioigniter-admin-settings' );
// }
} }
/** /**
@ -275,7 +291,8 @@ class AudioIgniter {
$labels = array( $labels = array(
'name' => esc_html_x( 'Playlists', 'post type general name', 'audioigniter' ), 'name' => esc_html_x( 'Playlists', 'post type general name', 'audioigniter' ),
'singular_name' => esc_html_x( 'Playlist', 'post type singular name', 'audioigniter' ), 'singular_name' => esc_html_x( 'Playlist', 'post type singular name', 'audioigniter' ),
'menu_name' => esc_html_x( 'Playlists', 'admin menu', 'audioigniter' ), 'menu_name' => esc_html_x( 'AudioIgniter', 'admin menu', 'audioigniter' ),
'all_items' => esc_html_x( 'All Playlists', 'admin menu', 'audioigniter' ),
'name_admin_bar' => esc_html_x( 'Playlist', 'add new on admin bar', 'audioigniter' ), 'name_admin_bar' => esc_html_x( 'Playlist', 'add new on admin bar', 'audioigniter' ),
'add_new' => esc_html__( 'Add New Playlist', 'audioigniter' ), 'add_new' => esc_html__( 'Add New Playlist', 'audioigniter' ),
'add_new_item' => esc_html__( 'Add New Playlist', 'audioigniter' ), 'add_new_item' => esc_html__( 'Add New Playlist', 'audioigniter' ),
@ -1273,7 +1290,7 @@ class AudioIgniter {
$track_response['audio'] = $track['track_url']; $track_response['audio'] = $track['track_url'];
$track_response['buyUrl'] = $track['buy_link']; $track_response['buyUrl'] = $track['buy_link'];
$track_response['downloadUrl'] = $track['download_uses_track_url'] ? $track['track_url'] : $track['download_url']; $track_response['downloadUrl'] = $track['download_uses_track_url'] ? $track['track_url'] : $track['download_url'];
$track_response['downloadFilename'] = $this->get_filename_from_url( $track['download_url'] ); $track_response['downloadFilename'] = $this->get_filename_from_url( $track_response['downloadUrl'] );
if ( ! $track_response['downloadFilename'] ) { if ( ! $track_response['downloadFilename'] ) {
$track_response['downloadFilename'] = $track_response['downloadUrl']; $track_response['downloadFilename'] = $track_response['downloadUrl'];

View File

@ -2,7 +2,7 @@ module.exports = {
name: 'audioigniter', name: 'audioigniter',
paths: { paths: {
src: { src: {
styles: ['./assets/css/*.scss'], styles: ['./assets/css/**/*.scss'],
}, },
}, },
}; };

View File

@ -0,0 +1,169 @@
<?php
/**
* AudioIgniter_Admin_Page_Upsell class.
*
* @since 2.0.0
*/
class AudioIgniter_Admin_Page_Upsell {
/**
* Settings tabs.
*
* @since 2.0.0
*
* @var array
*/
protected $tabs = array();
/**
* Settings page slug.
*
* @since 2.0.0
*/
protected static $page_slug = 'audioigniter-upsell';
/**
* @since 2.0.0
*/
public function __construct() {
add_action( 'admin_menu', array( $this, 'register' ) );
$this->tabs = array(
'general' => array(
'title' => _x( 'General', 'settings tab title', 'audioigniter' ),
'callback' => array( $this, 'tab_general' ),
),
);
}
/**
* Register the page
*
* @since 2.0.0
*
* @return void
*/
public function register() {
$page_slug = 'edit.php?post_type=' . AudioIgniter()->post_type;
add_submenu_page( $page_slug, __( 'AudioIgniter Settings', 'audioigniter' ), __( 'Go Pro!', 'audioigniter' ), 'manage_options', self::$page_slug, array( $this, 'render_page' ) );
}
/**
* Renders the onboarding page.
*
* @since 2.0.0
*/
public function render_page() {
$active_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
if ( ! array_key_exists( $active_tab, $this->tabs ) ) {
reset( $this->tabs );
$active_tab = key( $this->tabs );
}
?>
<div class="wrap ai-settings-wrap">
<h2 class="ai-settings-header-title">
<?php esc_html_e( 'AudioIgniter Settings', 'audioigniter' ); ?>
</h2>
<div class="ai-settings-main-wrap">
<div class="ai-settings-wp-notices">
<hr class="wp-header-end">
</div>
<div class="ai-settings-main">
<?php $this->generate_tabs( $active_tab ); ?>
</div>
</div>
</div>
<?php
}
/**
* Creates the navigation tabs.
*
* @since 2.0.0
*/
public function generate_tabs( $active_tab ) {
?>
<div class="ai-settings-main-content-nav-header ai-settings-box">
<div class="ai-settings-main-content-nav">
<?php foreach ( $this->tabs as $tab => $tab_info ) : ?>
<?php if ( empty( $tab_info['title'] ) ) {
continue;
} ?>
<a href="<?php echo esc_url( $this->get_tab_url( $tab ) ); ?>" class="ai-settings-main-content-nav-link <?php echo esc_attr( $active_tab === $tab ? 'is-active' : '' ); ?>"><?php echo esc_html( $tab_info['title'] ); ?></a>
<?php endforeach; ?>
</div>
</div>
<div class="ai-settings-main-content tab-content-<?php echo esc_attr( $active_tab ); ?>">
<?php if ( is_callable( $this->tabs[ $active_tab ]['callback'] ) ) {
call_user_func( $this->tabs[ $active_tab ]['callback'], $active_tab );
} ?>
</div>
<?php
}
/**
* @since 2.0.0
*/
public function tab_general( $active_tab ) {
$stats_enabled = false;
?>
<form method="post" action="options.php">
<div style="border:1px solid black; padding: 50px 15px; background-color: white;">
TODO: Leave disabled option below and write some upsell stuff. Maybe add images. Or replace everything with upsell info.
</div>
<table class="form-table">
<tr>
<th scope="row"><label for="audioigniter_stats_enabled"><?php esc_html_e( 'Analytics', 'audioigniter' ); ?></label></th>
<td>
<label for="audioigniter_stats_enabled">
<input disabled type="checkbox" id="upsell_stats_enabled" name="upsell_stats_enabled" value="1">
<?php esc_html_e( 'Enable analytics', 'audioigniter' ); ?>
</label>
<p class="description" id="tagline-description">
<?php esc_html_e( 'When disabled, no new events will be logged and processed into the database.', 'audioigniter' ); ?>
</p>
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
<?php
}
/**
* Returns the setting page's URL.
*
* @since 2.0.0
*
* @return string
*/
private function get_page_url() {
return add_query_arg( array(
'post_type' => 'ai_playlist',
'page' => self::$page_slug,
), admin_url( 'edit.php' ) );
}
/**
* Returns the URL of a specific tab.
*
* @since 2.0.0
*
* @return string
*/
private function get_tab_url( $tab ) {
return add_query_arg( array(
'tab' => $tab,
), $this->get_page_url() );
}
}

View File

@ -2,7 +2,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: AudioIgniter\n" "Project-Id-Version: AudioIgniter\n"
"POT-Creation-Date: 2022-06-28 14:39+0300\n" "POT-Creation-Date: 2023-04-18 22:08+0300\n"
"PO-Revision-Date: 2016-08-29 19:22+0300\n" "PO-Revision-Date: 2016-08-29 19:22+0300\n"
"Last-Translator: Anastis Sourgoutsidis <anastis@cssigniter.com>\n" "Last-Translator: Anastis Sourgoutsidis <anastis@cssigniter.com>\n"
"Language-Team: Anastis Sourgoutsidis <anastis@cssigniter.com>\n" "Language-Team: Anastis Sourgoutsidis <anastis@cssigniter.com>\n"
@ -10,7 +10,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
"X-Generator: Poedit 3.1\n" "X-Generator: Poedit 3.2.2\n"
"X-Poedit-Basepath: ..\n" "X-Poedit-Basepath: ..\n"
"X-Poedit-WPHeader: audioigniter.php\n" "X-Poedit-WPHeader: audioigniter.php\n"
"X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SourceCharset: UTF-8\n"
@ -22,351 +22,383 @@ msgstr ""
"X-Poedit-SearchPathExcluded-0: *.js\n" "X-Poedit-SearchPathExcluded-0: *.js\n"
#. translators: %s is the track's title. #. translators: %s is the track's title.
#: audioigniter.php:216 #: audioigniter.php:218
#, php-format #, php-format
msgid "Play %s" msgid "Play %s"
msgstr "" msgstr ""
#. translators: %s is the track's title. #. translators: %s is the track's title.
#: audioigniter.php:218 #: audioigniter.php:220
#, php-format #, php-format
msgid "Pause %s" msgid "Pause %s"
msgstr "" msgstr ""
#: audioigniter.php:219 #: audioigniter.php:221
msgid "Previous track" msgid "Previous track"
msgstr "" msgstr ""
#: audioigniter.php:220 #: audioigniter.php:222
msgid "Next track" msgid "Next track"
msgstr "" msgstr ""
#: audioigniter.php:221 #: audioigniter.php:223
msgid "Toggle track listing repeat" msgid "Toggle track listing repeat"
msgstr "" msgstr ""
#: audioigniter.php:222 #: audioigniter.php:224
msgid "Toggle track repeat" msgid "Toggle track repeat"
msgstr "" msgstr ""
#: audioigniter.php:223 #: audioigniter.php:225
msgid "Toggle track listing visibility" msgid "Toggle track listing visibility"
msgstr "" msgstr ""
#: audioigniter.php:224 #: audioigniter.php:226
msgid "Buy this track" msgid "Buy this track"
msgstr "" msgstr ""
#: audioigniter.php:225 #: audioigniter.php:227
msgid "Download this track" msgid "Download this track"
msgstr "" msgstr ""
#: audioigniter.php:226 #: audioigniter.php:228
msgid "Volume Up" msgid "Volume Up"
msgstr "" msgstr ""
#: audioigniter.php:227 #: audioigniter.php:229
msgid "Volume Down" msgid "Volume Down"
msgstr "" msgstr ""
#: audioigniter.php:228 #: audioigniter.php:230
msgid "Open track lyrics" msgid "Open track lyrics"
msgstr "" msgstr ""
#: audioigniter.php:229 #: audioigniter.php:231
msgid "Set playback rate" msgid "Set playback rate"
msgstr "" msgstr ""
#: audioigniter.php:230 #: audioigniter.php:232
msgid "Skip forward" msgid "Skip forward"
msgstr "" msgstr ""
#: audioigniter.php:231 #: audioigniter.php:233
msgid "Skip backward" msgid "Skip backward"
msgstr "" msgstr ""
#: audioigniter.php:232 #: audioigniter.php:234
msgid "Shuffle" msgid "Shuffle"
msgstr "" msgstr ""
#: audioigniter.php:237 #: audioigniter.php:247
msgid "" msgid ""
"Do you really want to remove all tracks? (This will not delete your audio " "Do you really want to remove all tracks? (This will not delete your audio "
"files)." "files)."
msgstr "" msgstr ""
#: audioigniter.php:238 #: audioigniter.php:248
msgid "Select or upload audio media" msgid "Select or upload audio media"
msgstr "" msgstr ""
#: audioigniter.php:239 #: audioigniter.php:249
msgid "Select a cover image" msgid "Select a cover image"
msgstr "" msgstr ""
#: audioigniter.php:276 #: audioigniter.php:292
msgctxt "post type general name" msgctxt "post type general name"
msgid "Playlists" msgid "Playlists"
msgstr "" msgstr ""
#: audioigniter.php:277 audioigniter.php:292 #: audioigniter.php:293 audioigniter.php:309
msgctxt "post type singular name" msgctxt "post type singular name"
msgid "Playlist" msgid "Playlist"
msgstr "" msgstr ""
#: audioigniter.php:278 #: audioigniter.php:294
msgctxt "admin menu" msgctxt "admin menu"
msgid "Playlists" msgid "AudioIgniter"
msgstr "" msgstr ""
#: audioigniter.php:279 #: audioigniter.php:295
msgctxt "admin menu"
msgid "All Playlists"
msgstr ""
#: audioigniter.php:296
msgctxt "add new on admin bar" msgctxt "add new on admin bar"
msgid "Playlist" msgid "Playlist"
msgstr "" msgstr ""
#: audioigniter.php:280 audioigniter.php:281 #: audioigniter.php:297 audioigniter.php:298
msgid "Add New Playlist" msgid "Add New Playlist"
msgstr "" msgstr ""
#: audioigniter.php:282 #: audioigniter.php:299
msgid "Edit Playlist" msgid "Edit Playlist"
msgstr "" msgstr ""
#: audioigniter.php:283 #: audioigniter.php:300
msgid "New Playlist" msgid "New Playlist"
msgstr "" msgstr ""
#: audioigniter.php:284 #: audioigniter.php:301
msgid "View Playlist" msgid "View Playlist"
msgstr "" msgstr ""
#: audioigniter.php:285 #: audioigniter.php:302
msgid "Search Playlists" msgid "Search Playlists"
msgstr "" msgstr ""
#: audioigniter.php:286 #: audioigniter.php:303
msgid "No playlists found" msgid "No playlists found"
msgstr "" msgstr ""
#: audioigniter.php:287 #: audioigniter.php:304
msgid "No playlists found in the trash" msgid "No playlists found in the trash"
msgstr "" msgstr ""
#: audioigniter.php:312 audioigniter.php:838 #: audioigniter.php:329 audioigniter.php:855
msgid "Tracks" msgid "Tracks"
msgstr "" msgstr ""
#: audioigniter.php:313 #: audioigniter.php:330
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
#: audioigniter.php:314 audioigniter.php:1303 #: audioigniter.php:331 audioigniter.php:1320
msgid "Shortcode" msgid "Shortcode"
msgstr "" msgstr ""
#: audioigniter.php:372 #: audioigniter.php:389
msgid "AudioIgniter Logo" msgid "AudioIgniter Logo"
msgstr "" msgstr ""
#: audioigniter.php:381 #: audioigniter.php:398
msgid "Upgrade to Pro" msgid "Upgrade to Pro"
msgstr "" msgstr ""
#: audioigniter.php:405 #: audioigniter.php:422
msgid "Support" msgid "Support"
msgstr "" msgstr ""
#: audioigniter.php:409 #: audioigniter.php:426
msgid "Documentation" msgid "Documentation"
msgstr "" msgstr ""
#: audioigniter.php:413 #: audioigniter.php:430
msgid "Rate this plugin" msgid "Rate this plugin"
msgstr "" msgstr ""
#. translators: %s is a URL. #. translators: %s is a URL.
#: audioigniter.php:436 #: audioigniter.php:453
#, php-format #, php-format
msgid "" msgid ""
"Thank you for creating with <a href=\"%s\" target=\"_blank\">AudioIgniter</a>" "Thank you for creating with <a href=\"%s\" target=\"_blank\">AudioIgniter</a>"
msgstr "" msgstr ""
#: audioigniter.php:482 #: audioigniter.php:499
msgid "Toggle track visibility" msgid "Toggle track visibility"
msgstr "" msgstr ""
#: audioigniter.php:493 #: audioigniter.php:510
msgid "Remove Cover Image" msgid "Remove Cover Image"
msgstr "" msgstr ""
#: audioigniter.php:506 #: audioigniter.php:523
msgid "Upload Cover" msgid "Upload Cover"
msgstr "" msgstr ""
#: audioigniter.php:524 audioigniter.php:531 #: audioigniter.php:541 audioigniter.php:548
msgid "Title" msgid "Title"
msgstr "" msgstr ""
#: audioigniter.php:539 audioigniter.php:546 #: audioigniter.php:556 audioigniter.php:563
msgid "Artist" msgid "Artist"
msgstr "" msgstr ""
#: audioigniter.php:555 audioigniter.php:562 #: audioigniter.php:572 audioigniter.php:579
msgid "Buy link" msgid "Buy link"
msgstr "" msgstr ""
#: audioigniter.php:575 audioigniter.php:584 #: audioigniter.php:592 audioigniter.php:601
msgid "Audio file or radio stream" msgid "Audio file or radio stream"
msgstr "" msgstr ""
#: audioigniter.php:588 #: audioigniter.php:605
msgid "Upload" msgid "Upload"
msgstr "" msgstr ""
#: audioigniter.php:599 audioigniter.php:606 #: audioigniter.php:616 audioigniter.php:623
msgid "Download URL" msgid "Download URL"
msgstr "" msgstr ""
#: audioigniter.php:620 #: audioigniter.php:637
msgid "Remove Track" msgid "Remove Track"
msgstr "" msgstr ""
#: audioigniter.php:635 #: audioigniter.php:652
msgid "Add Track" msgid "Add Track"
msgstr "" msgstr ""
#: audioigniter.php:642 #: audioigniter.php:659
msgid "Clear Playlist" msgid "Clear Playlist"
msgstr "" msgstr ""
#: audioigniter.php:648 #: audioigniter.php:665
msgid "Expand All" msgid "Expand All"
msgstr "" msgstr ""
#: audioigniter.php:651 #: audioigniter.php:668
msgid "Collapse All" msgid "Collapse All"
msgstr "" msgstr ""
#: audioigniter.php:690 #: audioigniter.php:707
msgid "Player &amp; Track listing" msgid "Player &amp; Track listing"
msgstr "" msgstr ""
#: audioigniter.php:695 #: audioigniter.php:712
msgid "Player Type" msgid "Player Type"
msgstr "" msgstr ""
#: audioigniter.php:726 #: audioigniter.php:743
msgid "Show track listing by default" msgid "Show track listing by default"
msgstr "" msgstr ""
#: audioigniter.php:740 #: audioigniter.php:757
msgid "Show track listing visibility toggle button" msgid "Show track listing visibility toggle button"
msgstr "" msgstr ""
#: audioigniter.php:754 #: audioigniter.php:771
msgid "Reverse track order" msgid "Reverse track order"
msgstr "" msgstr ""
#: audioigniter.php:760 #: audioigniter.php:777
msgid "Starting volume" msgid "Starting volume"
msgstr "" msgstr ""
#: audioigniter.php:771 #: audioigniter.php:788
msgid "0-100" msgid "0-100"
msgstr "" msgstr ""
#: audioigniter.php:776 #: audioigniter.php:793
msgid "Enter a value between 0 and 100 in increments of 10" msgid "Enter a value between 0 and 100 in increments of 10"
msgstr "" msgstr ""
#: audioigniter.php:790 #: audioigniter.php:807
msgid "Limit track listing height" msgid "Limit track listing height"
msgstr "" msgstr ""
#: audioigniter.php:796 audioigniter.php:806 #: audioigniter.php:813 audioigniter.php:823
msgid "Track listing height" msgid "Track listing height"
msgstr "" msgstr ""
#: audioigniter.php:811 #: audioigniter.php:828
msgid "Set a number of pixels" msgid "Set a number of pixels"
msgstr "" msgstr ""
#: audioigniter.php:817 #: audioigniter.php:834
msgid "Maximum player width" msgid "Maximum player width"
msgstr "" msgstr ""
#: audioigniter.php:825 #: audioigniter.php:842
msgid "Automatic width" msgid "Automatic width"
msgstr "" msgstr ""
#: audioigniter.php:830 #: audioigniter.php:847
#, php-format #, php-format
msgid "" msgid ""
"Set a number of pixels, or leave empty to automatically cover 100% of the " "Set a number of pixels, or leave empty to automatically cover 100% of the "
"available area (recommended)." "available area (recommended)."
msgstr "" msgstr ""
#: audioigniter.php:850 #: audioigniter.php:867
msgid "Show track numbers in tracklist" msgid "Show track numbers in tracklist"
msgstr "" msgstr ""
#: audioigniter.php:864 #: audioigniter.php:881
msgid "Show track covers in tracklist" msgid "Show track covers in tracklist"
msgstr "" msgstr ""
#: audioigniter.php:878 #: audioigniter.php:895
msgid "Show active track's cover" msgid "Show active track's cover"
msgstr "" msgstr ""
#: audioigniter.php:892 #: audioigniter.php:909
msgid "Show artist names" msgid "Show artist names"
msgstr "" msgstr ""
#: audioigniter.php:906 #: audioigniter.php:923
msgid "Show track extra buttons (buy link, download button etc)" msgid "Show track extra buttons (buy link, download button etc)"
msgstr "" msgstr ""
#: audioigniter.php:920 #: audioigniter.php:937
msgid "Open buy links in new window" msgid "Open buy links in new window"
msgstr "" msgstr ""
#: audioigniter.php:928 #: audioigniter.php:945
msgid "Track &amp; Track listing repeat" msgid "Track &amp; Track listing repeat"
msgstr "" msgstr ""
#: audioigniter.php:940 #: audioigniter.php:957
msgid "Repeat track listing enabled by default" msgid "Repeat track listing enabled by default"
msgstr "" msgstr ""
#: audioigniter.php:954 #: audioigniter.php:971
msgid "Show track listing repeat toggle button" msgid "Show track listing repeat toggle button"
msgstr "" msgstr ""
#: audioigniter.php:971 #: audioigniter.php:988
msgid "Show \"Powered by AudioIgniter\" link" msgid "Show \"Powered by AudioIgniter\" link"
msgstr "" msgstr ""
#: audioigniter.php:975 #: audioigniter.php:992
msgid "" msgid ""
"We've put a great deal of effort into building this plugin. If you feel like " "We've put a great deal of effort into building this plugin. If you feel like "
"it, let others know about it by enabling this option." "it, let others know about it by enabling this option."
msgstr "" msgstr ""
#: audioigniter.php:995 #: audioigniter.php:1012
msgid "Grab the shortcode" msgid "Grab the shortcode"
msgstr "" msgstr ""
#: audioigniter.php:1029 #: audioigniter.php:1046
msgid "Full Player" msgid "Full Player"
msgstr "" msgstr ""
#: audioigniter.php:1034 #: audioigniter.php:1051
msgid "Simple Player" msgid "Simple Player"
msgstr "" msgstr ""
#: audioigniter.php:1257 #: audioigniter.php:1274
msgid "ID doesn't match a playlist" msgid "ID doesn't match a playlist"
msgstr "" msgstr ""
#: inc/class-audioigniter-admin-page-upsell.php:32
msgctxt "settings tab title"
msgid "General"
msgstr ""
#: inc/class-audioigniter-admin-page-upsell.php:47
#: inc/class-audioigniter-admin-page-upsell.php:65
msgid "AudioIgniter Settings"
msgstr ""
#: inc/class-audioigniter-admin-page-upsell.php:47
msgid "Go Pro!"
msgstr ""
#: inc/class-audioigniter-admin-page-upsell.php:123
msgid "Analytics"
msgstr ""
#: inc/class-audioigniter-admin-page-upsell.php:127
msgid "Enable analytics"
msgstr ""
#: inc/class-audioigniter-admin-page-upsell.php:130
msgid ""
"When disabled, no new events will be logged and processed into the database."
msgstr ""
#. Plugin Name of the plugin/theme #. Plugin Name of the plugin/theme
msgid "AudioIgniter" msgid "AudioIgniter"
msgstr "" msgstr ""

File diff suppressed because one or more lines are too long

View File

@ -22,6 +22,8 @@
* http://api.jqueryui.com/category/ui-core/ * http://api.jqueryui.com/category/ui-core/
*/ */
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
/** /**
* @license React * @license React
* react-dom.production.min.js * react-dom.production.min.js

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
<!doctype html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>AudioIgniter</title><style>body { <!doctype html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>AudioIgniter</title><style>body {
padding-bottom: 120px; padding-bottom: 120px;
}</style><script defer="defer" src="style.js"></script><script defer="defer" src="app.js"></script><link href="style.css" rel="stylesheet"></head><body><div id="audioigniter-2799" class="audioigniter-root" data-player-type="full" data-tracks-url="/dev-tracks.json" data-display-active-cover="true" data-display-tracklist-covers="true" data-display-credits="true" data-display-tracklist="true" data-allow-tracklist-toggle="true" data-allow-tracklist-loop="true" data-allow-track-loop="true" data-allow-playback-rate="true" data-display-track-no="true" data-display-artist-names="true" data-display-buy-buttons="true" data-buy-buttons-target="true" data-volume="50" data-cycle-tracks="true" data-limit-tracklist-height="true" data-tracklist-height="185" data-reverse-track-order="false" data-skip-amount="15" data-max-width="600px" data-initial-track="1" data-stop-on-finish="false" data-tracks-delay="5" data-timer-countdown="false" data-shuffle="true" data-shuffle-default="false" data-soundcloud-client-id="" data-remember-last="true" data-player-buttons='[ }</style><script defer="defer" src="style.js"></script><script defer="defer" src="app.js"></script><link href="style.css" rel="stylesheet"></head><body><div id="audioigniter-01" class="audioigniter-root" data-player-type="full" data-tracks-url="/dev-tracks.json" data-display-active-cover="true" data-display-tracklist-covers="true" data-display-credits="true" data-display-tracklist="true" data-allow-tracklist-toggle="true" data-allow-tracklist-loop="true" data-allow-track-loop="true" data-allow-playback-rate="true" data-display-track-no="true" data-display-artist-names="true" data-display-buy-buttons="true" data-buy-buttons-target="true" data-volume="50" data-cycle-tracks="true" data-limit-tracklist-height="true" data-tracklist-height="185" data-reverse-track-order="false" data-skip-amount="15" data-max-width="600px" data-initial-track="1" data-stop-on-finish="true" data-tracks-delay="5" data-timer-countdown="false" data-shuffle="true" data-shuffle-default="true" data-soundcloud-client-id="" data-remember-last="true" data-player-buttons='[
{ {
"title": "CSSIgniter", "title": "CSSIgniter",
"url": "https://cssigniter.com", "url": "https://cssigniter.com",
@ -17,7 +17,7 @@
"icon": "" "icon": ""
} }
] ]
'></div><div id="audioigniter-2999" class="audioigniter-root" data-player-type="simple" data-tracks-url="/dev-tracks.json" data-display-credits="true" data-display-track-no="true" data-allow-playback-rate="true" data-display-artist-names="true" data-display-buy-buttons="true" data-buy-buttons-target="true" data-allow-track-loop="true" data-volume="50" data-reverse-track-order="false" data-max-width="600px" data-initial-track="3" data-stop-on-finish="false" data-tracks-delay="0" data-timer-countdown="false" data-shuffle="true" data-soundcloud-client-id="" data-player-buttons='[ '></div><div id="audioigniter-02" class="audioigniter-root" data-player-type="simple" data-tracks-url="/dev-tracks.json" data-display-credits="true" data-display-track-no="true" data-allow-playback-rate="true" data-display-artist-names="true" data-display-buy-buttons="true" data-buy-buttons-target="true" data-allow-track-loop="true" data-volume="50" data-reverse-track-order="false" data-max-width="600px" data-initial-track="3" data-stop-on-finish="false" data-tracks-delay="0" data-timer-countdown="false" data-shuffle="true" data-soundcloud-client-id="" data-player-buttons='[
{ {
"title": "CSSIgniter", "title": "CSSIgniter",
"url": "https://cssigniter.com", "url": "https://cssigniter.com",
@ -34,7 +34,7 @@
"icon": "" "icon": ""
} }
] ]
'></div><div id="audioigniter-2519" class="audioigniter-root" data-track='{"title":"Sunrise","subtitle":"Thoribass","audio":"https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3","buyUrl":"https:\/\/google.com","downloadUrl":"https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3","cover":"https:\/\/www.cssigniter.com\/demos\/audioigniter\/wp-content\/uploads\/sites\/48\/2016\/08\/CyberSDF-Flame-and-Go.jpg","lyrics":"Some lyrics"}' data-display-active-cover="false" data-display-credits="true" data-allow-playback-rate="false" data-display-buy-buttons="true" data-volume="100" data-skip-amount="0" data-stop-on-finish="true" data-timer-countdown="false" data-player-type="full" data-tracks-url="" data-display-tracklist="false" data-allow-tracklist-toggle="true" data-allow-tracklist-loop="true" data-allow-track-loop="true" data-display-track-no="false" data-display-artist-names="true" data-buy-buttons-target="true" data-cycle-tracks="false" data-limit-tracklist-height="false" data-tracklist-height="185" data-reverse-track-order="false" data-max-width="600px" data-initial-track="1" data-tracks-delay="0" data-shuffle="false" data-shuffle-default="false" data-remember-last="false"></div><div id="audioigniter-8999" class="audioigniter-root" data-player-type="global-footer" data-tracks-url="/dev-tracks.json" data-display-active-cover="true" data-display-tracklist-covers="true" data-display-credits="true" data-display-tracklist="false" data-allow-tracklist-toggle="true" data-allow-tracklist-loop="true" data-allow-track-loop="true" data-display-track-no="true" data-allow-playback-rate="true" data-display-artist-names="true" data-display-buy-buttons="true" data-buy-buttons-target="true" data-volume="50" data-skip-amount="15" data-cycle-tracks="false" data-limit-tracklist-height="true" data-tracklist-height="185" data-reverse-track-order="false" data-max-width="600px" data-initial-track="1" data-stop-on-finish="false" data-tracks-delay="0" data-timer-countdown="true" data-shuffle="true" data-soundcloud-client-id="" data-player-buttons='[ '></div><div id="audioigniter-03" class="audioigniter-root" data-track='{"title":"Sunrise","subtitle":"Thoribass","audio":"https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3","buyUrl":"https:\/\/google.com","downloadUrl":"https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3","cover":"https:\/\/www.cssigniter.com\/demos\/audioigniter\/wp-content\/uploads\/sites\/48\/2016\/08\/CyberSDF-Flame-and-Go.jpg","lyrics":"Some lyrics"}' data-display-active-cover="false" data-display-credits="true" data-allow-playback-rate="false" data-display-buy-buttons="true" data-volume="100" data-skip-amount="0" data-stop-on-finish="true" data-timer-countdown="false" data-player-type="full" data-tracks-url="" data-display-tracklist="false" data-allow-tracklist-toggle="true" data-allow-tracklist-loop="true" data-allow-track-loop="true" data-display-track-no="false" data-display-artist-names="true" data-buy-buttons-target="true" data-cycle-tracks="false" data-limit-tracklist-height="false" data-tracklist-height="185" data-reverse-track-order="false" data-max-width="600px" data-initial-track="1" data-tracks-delay="0" data-shuffle="false" data-shuffle-default="false" data-remember-last="false"></div><div id="audioigniter-04" class="audioigniter-root" data-player-type="global-footer" data-tracks-url="/dev-tracks.json" data-display-active-cover="true" data-display-tracklist-covers="true" data-display-credits="true" data-display-tracklist="false" data-allow-tracklist-toggle="true" data-allow-tracklist-loop="true" data-allow-track-loop="true" data-display-track-no="true" data-allow-playback-rate="true" data-display-artist-names="true" data-display-buy-buttons="true" data-buy-buttons-target="true" data-volume="50" data-skip-amount="15" data-cycle-tracks="false" data-limit-tracklist-height="true" data-tracklist-height="185" data-reverse-track-order="false" data-max-width="600px" data-initial-track="1" data-stop-on-finish="false" data-tracks-delay="0" data-timer-countdown="true" data-shuffle="true" data-soundcloud-client-id="" data-remember-last="true" data-player-buttons='[
{ {
"title": "CSSIgniter", "title": "CSSIgniter",
"url": "https://cssigniter.com", "url": "https://cssigniter.com",

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,7 @@
"audio": "https://www.cssigniter.com/assets/audioigniter/sunrise.mp3", "audio": "https://www.cssigniter.com/assets/audioigniter/sunrise.mp3",
"buyUrl": "https://www.cssigniter.com", "buyUrl": "https://www.cssigniter.com",
"downloadUrl": "https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3", "downloadUrl": "https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3",
"downloadFilename": "sunrise.mp3",
"cover": "https://www.cssigniter.com/demos/audioigniter/wp-content/uploads/sites/48/2016/08/CyberSDF-Flame-and-Go.jpg", "cover": "https://www.cssigniter.com/demos/audioigniter/wp-content/uploads/sites/48/2016/08/CyberSDF-Flame-and-Go.jpg",
"lyrics": "Here in my mind\nYou know you might find\nSomething that you\n\nYou thought you once knew\nBut now it's all gone\nAnd you know it's no fun\n\nYeah I know it's no fun\nOh I know it's no fun\nI'm free to be whatever I\nWhatever I choose\nAnd I'll sing the blues if I want\nI'm free to be whatever I\nWhatever I choose\nAnd I'll sing the blues if I want\nWhatever you do\nWhatever you say\nYeah I know it's alright" "lyrics": "Here in my mind\nYou know you might find\nSomething that you\n\nYou thought you once knew\nBut now it's all gone\nAnd you know it's no fun\n\nYeah I know it's no fun\nOh I know it's no fun\nI'm free to be whatever I\nWhatever I choose\nAnd I'll sing the blues if I want\nI'm free to be whatever I\nWhatever I choose\nAnd I'll sing the blues if I want\nWhatever you do\nWhatever you say\nYeah I know it's alright"
}, },
@ -13,6 +14,7 @@
"subtitle": "The Fisherman", "subtitle": "The Fisherman",
"audio": "https://www.cssigniter.com/assets/audioigniter/sunrise.mp3", "audio": "https://www.cssigniter.com/assets/audioigniter/sunrise.mp3",
"buyUrl": "https://www.cssigniter.com", "buyUrl": "https://www.cssigniter.com",
"downloadFilename": "fisherman.mp3",
"downloadUrl": "https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3", "downloadUrl": "https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3",
"cover": "https://www.cssigniter.com/demos/audioigniter/wp-content/uploads/sites/48/2016/08/Thoribass-Sunrise.jpg" "cover": "https://www.cssigniter.com/demos/audioigniter/wp-content/uploads/sites/48/2016/08/Thoribass-Sunrise.jpg"
}, },
@ -32,13 +34,6 @@
"downloadUrl": "https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3", "downloadUrl": "https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3",
"cover": "" "cover": ""
}, },
{
"title": "Is It Because I'm Black (David August Reconstruction)",
"subtitle": "Syl Johnson (SoundCloud)",
"audio": "https://soundcloud.com/enterofficial/maceo-plex-b2b-richie-hawtin-enterweek-11-sake-bar-space-ibiza-september-10th-2015",
"buyUrl": "",
"cover": "https://www.cssigniter.com/demos/audioigniter/wp-content/uploads/sites/48/2016/08/Rocavaco-Remix-Safety-Guide.jpg"
},
{ {
"title": "Deep House Radio", "title": "Deep House Radio",
"subtitle": "", "subtitle": "",

View File

@ -58,6 +58,7 @@
"webpack-merge": "^4.1.0" "webpack-merge": "^4.1.0"
}, },
"dependencies": { "dependencies": {
"@fingerprintjs/fingerprintjs": "^3.3.6",
"classnames": "2.3.0", "classnames": "2.3.0",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react": "^18.2.0", "react": "^18.2.0",

View File

@ -13,7 +13,7 @@
</head> </head>
<body> <body>
<div <div
id="audioigniter-2799" id="audioigniter-01"
class="audioigniter-root" class="audioigniter-root"
data-player-type="full" data-player-type="full"
data-tracks-url="/dev-tracks.json" data-tracks-url="/dev-tracks.json"
@ -37,11 +37,11 @@
data-skip-amount="15" data-skip-amount="15"
data-max-width="600px" data-max-width="600px"
data-initial-track="1" data-initial-track="1"
data-stop-on-finish="false" data-stop-on-finish="true"
data-tracks-delay="5" data-tracks-delay="5"
data-timer-countdown="false" data-timer-countdown="false"
data-shuffle="true" data-shuffle="true"
data-shuffle-default="false" data-shuffle-default="true"
data-soundcloud-client-id="" data-soundcloud-client-id=""
data-remember-last="true" data-remember-last="true"
data-player-buttons='[ data-player-buttons='[
@ -65,7 +65,7 @@
></div> ></div>
<div <div
id="audioigniter-2999" id="audioigniter-02"
class="audioigniter-root" class="audioigniter-root"
data-player-type="simple" data-player-type="simple"
data-tracks-url="/dev-tracks.json" data-tracks-url="/dev-tracks.json"
@ -106,7 +106,7 @@
></div> ></div>
<div <div
id="audioigniter-2519" id="audioigniter-03"
class="audioigniter-root" class="audioigniter-root"
data-track='{"title":"Sunrise","subtitle":"Thoribass","audio":"https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3","buyUrl":"https:\/\/google.com","downloadUrl":"https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3","cover":"https:\/\/www.cssigniter.com\/demos\/audioigniter\/wp-content\/uploads\/sites\/48\/2016\/08\/CyberSDF-Flame-and-Go.jpg","lyrics":"Some lyrics"}' data-track='{"title":"Sunrise","subtitle":"Thoribass","audio":"https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3","buyUrl":"https:\/\/google.com","downloadUrl":"https:\/\/www.cssigniter.com\/assets\/audioigniter\/sunrise.mp3","cover":"https:\/\/www.cssigniter.com\/demos\/audioigniter\/wp-content\/uploads\/sites\/48\/2016\/08\/CyberSDF-Flame-and-Go.jpg","lyrics":"Some lyrics"}'
@ -141,7 +141,7 @@
></div> ></div>
<div <div
id="audioigniter-8999" id="audioigniter-04"
class="audioigniter-root" class="audioigniter-root"
data-player-type="global-footer" data-player-type="global-footer"
data-tracks-url="/dev-tracks.json" data-tracks-url="/dev-tracks.json"
@ -170,6 +170,7 @@
data-timer-countdown="true" data-timer-countdown="true"
data-shuffle="true" data-shuffle="true"
data-soundcloud-client-id="" data-soundcloud-client-id=""
data-remember-last="true"
data-player-buttons='[ data-player-buttons='[
{ {
"title": "CSSIgniter", "title": "CSSIgniter",

View File

@ -25,6 +25,10 @@ if (process.env.NODE_ENV !== 'production') {
skip_backward: 'Skip backward', skip_backward: 'Skip backward',
shuffle: 'Shuffle', shuffle: 'Shuffle',
}; };
window.aiStats = {
apiUrl: '',
};
} }
const nodes = document.getElementsByClassName('audioigniter-root'); const nodes = document.getElementsByClassName('audioigniter-root');
@ -77,7 +81,7 @@ function renderApp(node) {
initialTrack: parseInt(node.getAttribute('data-initial-track'), 10), initialTrack: parseInt(node.getAttribute('data-initial-track'), 10),
delayBetweenTracks: parseInt(node.getAttribute('data-tracks-delay'), 10), delayBetweenTracks: parseInt(node.getAttribute('data-tracks-delay'), 10),
stopOnTrackFinish: JSON.parse(node.getAttribute('data-stop-on-finish')), stopOnTrackFinish: JSON.parse(node.getAttribute('data-stop-on-finish')),
defaultShuffle: JSON.parse(node.getAttribute('data-shuffle')), defaultShuffle: JSON.parse(node.getAttribute('data-shuffle-default')),
shuffleEnabled: JSON.parse(node.getAttribute('data-shuffle')), shuffleEnabled: JSON.parse(node.getAttribute('data-shuffle')),
countdownTimerByDefault: JSON.parse( countdownTimerByDefault: JSON.parse(
node.getAttribute('data-timer-countdown'), node.getAttribute('data-timer-countdown'),

View File

@ -73,6 +73,7 @@ const propTypes = {
icon: PropTypes.string, icon: PropTypes.string,
}).isRequired, }).isRequired,
), ),
playerId: PropTypes.string,
}; };
const GlobalFooterPlayer = ({ const GlobalFooterPlayer = ({
@ -83,6 +84,7 @@ const GlobalFooterPlayer = ({
position, position,
duration, duration,
playbackRate, playbackRate,
playerId,
currentTrack, currentTrack,
playTrack, playTrack,
@ -312,6 +314,7 @@ const GlobalFooterPlayer = ({
onTrackClick={playTrack} onTrackClick={playTrack}
onTrackLoop={allowTrackLoop ? setTrackCycling : undefined} onTrackLoop={allowTrackLoop ? setTrackCycling : undefined}
repeatingTrackIndex={repeatingTrackIndex} repeatingTrackIndex={repeatingTrackIndex}
playerId={playerId}
/> />
{playerButtons?.length > 0 && <PlayerButtons buttons={playerButtons} />} {playerButtons?.length > 0 && <PlayerButtons buttons={playerButtons} />}

View File

@ -80,10 +80,12 @@ const propTypes = {
icon: PropTypes.string, icon: PropTypes.string,
}).isRequired, }).isRequired,
), ),
playerId: PropTypes.string,
}; };
const Player = ({ const Player = ({
tracks, tracks,
playerId,
playStatus, playStatus,
activeIndex, activeIndex,
volume, volume,
@ -345,6 +347,7 @@ const Player = ({
onTrackClick={playTrack} onTrackClick={playTrack}
onTrackLoop={allowTrackLoop ? setTrackCycling : undefined} onTrackLoop={allowTrackLoop ? setTrackCycling : undefined}
repeatingTrackIndex={repeatingTrackIndex} repeatingTrackIndex={repeatingTrackIndex}
playerId={playerId}
/> />
</div> </div>

View File

@ -10,6 +10,7 @@ import PlayerButtons from './components/PlayerButtons';
const propTypes = { const propTypes = {
tracks: PropTypes.arrayOf(PropTypes.object), tracks: PropTypes.arrayOf(PropTypes.object),
playerId: PropTypes.string,
playStatus: PropTypes.oneOf([ playStatus: PropTypes.oneOf([
Sound.status.PLAYING, Sound.status.PLAYING,
Sound.status.PAUSED, Sound.status.PAUSED,
@ -82,6 +83,7 @@ const SimplePlayer = props => {
setPlaybackRate={props.setPlaybackRate} setPlaybackRate={props.setPlaybackRate}
allowPlaybackRate={props.allowPlaybackRate} allowPlaybackRate={props.allowPlaybackRate}
buffering={props.buffering} buffering={props.buffering}
playerId={props.playerId}
/> />
</div> </div>

View File

@ -16,6 +16,10 @@ const Time = ({ countdown, position, duration }) => {
* @returns {string} - Time pretty formatted * @returns {string} - Time pretty formatted
*/ */
const renderFormattedTime = () => { const renderFormattedTime = () => {
if (!duration) {
return '00:00';
}
const positionInSeconds = showRemaining const positionInSeconds = showRemaining
? (duration - position) / 1000 ? (duration - position) / 1000
: position / 1000; : position / 1000;
@ -27,7 +31,7 @@ const Time = ({ countdown, position, duration }) => {
min = min >= 10 ? min : `0${min}`; min = min >= 10 ? min : `0${min}`;
sec = sec >= 10 ? sec : `0${sec}`; sec = sec >= 10 ? sec : `0${sec}`;
if (!Number.isNaN(sec)) { if (Number.isInteger(parseInt(sec, 10))) {
if (hours) { if (hours) {
time = `${hours}:${min}:${sec}`; time = `${hours}:${min}:${sec}`;
} else { } else {
@ -39,6 +43,10 @@ const Time = ({ countdown, position, duration }) => {
}; };
const handleClick = () => { const handleClick = () => {
if (!duration) {
return;
}
setShowRemaining(x => !x); setShowRemaining(x => !x);
}; };

View File

@ -46,6 +46,7 @@ const propTypes = {
setPlaybackRate: PropTypes.func, setPlaybackRate: PropTypes.func,
allowPlaybackRate: PropTypes.bool, allowPlaybackRate: PropTypes.bool,
buffering: PropTypes.bool, buffering: PropTypes.bool,
playerId: PropTypes.string,
}; };
const Track = ({ const Track = ({
@ -70,6 +71,7 @@ const Track = ({
setPlaybackRate, setPlaybackRate,
allowPlaybackRate, allowPlaybackRate,
buffering, buffering,
playerId,
}) => { }) => {
const { toggleLyricsModal } = useContext(AppContext); const { toggleLyricsModal } = useContext(AppContext);
const isPlaying = isActive && playStatus === Sound.status.PLAYING; const isPlaying = isActive && playStatus === Sound.status.PLAYING;
@ -125,6 +127,7 @@ const Track = ({
<TrackButtons <TrackButtons
buyButtonsTarget={buyButtonsTarget} buyButtonsTarget={buyButtonsTarget}
track={track}
buyUrl={track.buyUrl} buyUrl={track.buyUrl}
downloadUrl={track.downloadUrl} downloadUrl={track.downloadUrl}
downloadFilename={track.downloadFilename} downloadFilename={track.downloadFilename}
@ -138,6 +141,7 @@ const Track = ({
setPlaybackRate={setPlaybackRate} setPlaybackRate={setPlaybackRate}
allowPlaybackRate={allowPlaybackRate} allowPlaybackRate={allowPlaybackRate}
isPlaying={isPlaying} isPlaying={isPlaying}
playerId={playerId}
/> />
{hasProgressBar && ( {hasProgressBar && (

View File

@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { CartIcon, DownloadIcon, LyricsIcon, RefreshIcon } from './Icons'; import { CartIcon, DownloadIcon, LyricsIcon, RefreshIcon } from './Icons';
import events, { EVENT, normalizePlayerId } from '../services/events';
const propTypes = { const propTypes = {
buyButtonsTarget: PropTypes.bool, buyButtonsTarget: PropTypes.bool,
@ -16,6 +17,10 @@ const propTypes = {
setPlaybackRate: PropTypes.func, setPlaybackRate: PropTypes.func,
allowPlaybackRate: PropTypes.bool, allowPlaybackRate: PropTypes.bool,
isPlaying: PropTypes.bool, isPlaying: PropTypes.bool,
track: PropTypes.shape({
audio: PropTypes.string.isRequired,
}).isRequired,
playerId: PropTypes.string,
}; };
const TrackButtons = ({ const TrackButtons = ({
@ -31,6 +36,8 @@ const TrackButtons = ({
playbackRate, playbackRate,
allowPlaybackRate, allowPlaybackRate,
isPlaying, isPlaying,
track,
playerId,
}) => { }) => {
if ( if (
buyUrl == null && buyUrl == null &&
@ -64,6 +71,13 @@ const TrackButtons = ({
download={downloadFilename} download={downloadFilename}
className="ai-track-btn" className="ai-track-btn"
role="button" role="button"
onClick={() => {
events.eventTrack({
event: EVENT.DOWNLOAD,
trackUrl: track.audio,
playerId: normalizePlayerId(playerId),
});
}}
aria-label={aiStrings.download_track} aria-label={aiStrings.download_track}
title={aiStrings.download_track} title={aiStrings.download_track}
> >

View File

@ -31,6 +31,7 @@ const propTypes = {
allowPlaybackRate: PropTypes.bool, allowPlaybackRate: PropTypes.bool,
buffering: PropTypes.bool, buffering: PropTypes.bool,
repeatingTrackIndex: PropTypes.bool, repeatingTrackIndex: PropTypes.bool,
playerId: PropTypes.string,
}; };
const Tracklist = ({ ...props }) => { const Tracklist = ({ ...props }) => {
@ -69,6 +70,7 @@ const Tracklist = ({ ...props }) => {
setPlaybackRate={props.setPlaybackRate} setPlaybackRate={props.setPlaybackRate}
allowPlaybackRate={props.allowPlaybackRate} allowPlaybackRate={props.allowPlaybackRate}
buffering={props.buffering} buffering={props.buffering}
playerId={props.playerId}
/> />
); );
})} })}

View File

@ -21,6 +21,7 @@ const propTypes = {
displayArtistNames: PropTypes.bool, displayArtistNames: PropTypes.bool,
onTrackLoop: PropTypes.func, onTrackLoop: PropTypes.func,
repeatingTrackIndex: PropTypes.number, repeatingTrackIndex: PropTypes.number,
playerId: PropTypes.string,
}; };
const TracklistWrap = ({ const TracklistWrap = ({
@ -40,6 +41,7 @@ const TracklistWrap = ({
displayCovers, displayCovers,
displayArtistNames, displayArtistNames,
repeatingTrackIndex, repeatingTrackIndex,
playerId,
}) => { }) => {
const scrollbarRef = useRef(null); const scrollbarRef = useRef(null);
@ -82,6 +84,7 @@ const TracklistWrap = ({
displayArtistNames={displayArtistNames} displayArtistNames={displayArtistNames}
onTrackLoop={onTrackLoop} onTrackLoop={onTrackLoop}
repeatingTrackIndex={repeatingTrackIndex} repeatingTrackIndex={repeatingTrackIndex}
playerId={playerId}
/> />
); );
}; };

View File

@ -1,82 +0,0 @@
import React, { useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import WaveSurfer from 'wavesurfer.js';
const propTypes = {
position: PropTypes.number.isRequired,
duration: PropTypes.number.isRequired,
audio: PropTypes.string,
setPosition: PropTypes.func.isRequired,
};
const WaveformProgressBar = ({ audio, position, duration, setPosition }) => {
const waveFormDomRef = useRef(null);
const wavesurfer = useRef(null);
useEffect(() => {
if (waveFormDomRef.current && audio) {
wavesurfer.current = WaveSurfer.create({
container: waveFormDomRef.current,
mediaControls: false,
height: 40,
barWidth: 2,
barGap: 2,
barRadius: 3,
responsive: true,
cursorWidth: 0,
backgroundColor: 'transparent',
progressColor: '#f70f5d',
waveColor: '#fff',
xhr: {
mode: 'no-cors',
},
});
wavesurfer.current.load(audio);
wavesurfer.current.on('ready', () => {
console.log('wavesurfer loaded');
});
}
return () => {
if (wavesurfer.current) {
wavesurfer.current.destroy();
}
};
}, [audio, waveFormDomRef.current]);
useEffect(() => {
// Sync wavesurfer with current playing position
const progress = position / duration;
if (wavesurfer.current && !Number.isNaN(progress)) {
wavesurfer.current.seekTo(progress || 0);
}
}, [position]);
const handleClick = event => {
if (setPosition == null) {
return;
}
const offsetX =
event.pageX - event.currentTarget.getBoundingClientRect().left;
const posX = offsetX / event.currentTarget.offsetWidth;
setPosition(posX * duration);
};
if (!audio) {
return null;
}
return (
<div className="ai-waveform-bar" onClick={handleClick}>
<div className="ai-waveform" ref={waveFormDomRef} />
<div className="ai-waveform-progress" />
</div>
);
};
WaveformProgressBar.propTypes = propTypes;
export default WaveformProgressBar;

View File

@ -0,0 +1,144 @@
/* global aiStats */
import isStreamTrack from '../../utils/isStreamTrack';
/**
* @enum EVENT
* @type {{PAUSE: string, PLAY: string, STOP: string, DOWNLOAD: string, SEEK: string}}
*/
export const EVENT = {
PLAY: 'PLAY',
PLAYING: 'PLAYING',
PAUSE: 'PAUSE',
STOP: 'STOP',
SEEK: 'SEEK',
DOWNLOAD: 'DOWNLOAD',
};
/**
* Normalizes a player ID.
*
* @param {String} playerId The player ID
* @returns {string|null}
*/
export const normalizePlayerId = playerId => {
return playerId?.replace('audioigniter-', '') ?? null;
};
/**
* Takes state and props from soundProvider and returns the formatted event data.
* @param state
* @param props
* @returns {{duration, position, trackUrl: *, playerId: *}}
*/
export const getEventMeta = (state, props) => {
const { activeIndex, tracks, position, duration } = state;
const { playerId } = props;
const track = tracks[activeIndex];
const { title, subtitle, audio } = track ?? {};
return {
trackUrl: audio,
// trackName: subtitle ? `${title} - ${subtitle}` : title,
trackTitle: title,
trackArtist: subtitle ?? '',
playerId: normalizePlayerId(playerId),
position,
duration,
isStream: isStreamTrack(audio),
};
};
class AudioIgniterEvents {
constructor() {
this.clientId = null;
this.queue = [];
if (!window.aiStats?.enabled) {
return;
}
this.eventQueueTimer();
this.initializeFingerprint();
// Flush the entire queue when the user ends their session.
window.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
this.eventQueueFlush();
}
});
}
initializeFingerprint = async () => {
const FingerprintJS = await import(/* webpackChunkName: "fingerprintjs" */ '@fingerprintjs/fingerprintjs');
const fingerprint = await FingerprintJS.load();
const result = await fingerprint.get();
this.clientId = result.visitorId;
};
fetch = async () => {
const headers = {
type: 'application/json',
};
const blob = new Blob([JSON.stringify(this.queue)], headers);
navigator.sendBeacon(`${aiStats.apiUrl}/log`, blob);
};
eventQueueTimer = () => {
setInterval(() => {
if (this.queue.length > 0) {
this.eventQueueFlush();
}
}, 15000);
};
eventQueueFlush = async () => {
await this.fetch();
this.queue = [];
};
eventTrack = ({
event,
trackUrl,
// trackName,
trackTitle,
trackArtist,
playerId,
position,
oldPosition,
duration,
isStream,
}) => {
if (!window.aiStats?.enabled) {
return;
}
// Failsafe for multi sound pausing, some tracks
// can be paused before they start due to external
// soundManager pausing (see playTrack event in soundProvider.js).
if (event === EVENT.PAUSE && position === 0) {
return;
}
this.queue.push({
event,
track_url: trackUrl,
// track_name: trackName,
track_title: trackTitle,
track_artist: trackArtist,
playlist_id: parseInt(playerId, 10),
timestamp: new Date().getTime(),
referrer_url: window.location.href,
event_data: {
position: Math.floor(position / 1000) ?? null,
old_position:
oldPosition != null ? Math.floor(oldPosition / 1000) : null,
duration: duration ? Math.floor(duration / 1000) : null,
},
client_fingerprint: this.clientId,
is_stream: isStream,
});
};
}
export default new AudioIgniterEvents();

View File

@ -6,6 +6,8 @@ import SoundCloud from '../utils/soundcloud';
import multiSoundDisabled from '../utils/multi-sound-disabled'; import multiSoundDisabled from '../utils/multi-sound-disabled';
import { getInitialTrackQueueAndIndex } from '../utils/getInitialTrackIndex'; import { getInitialTrackQueueAndIndex } from '../utils/getInitialTrackIndex';
import playerStorage from '../utils/playerStorage'; import playerStorage from '../utils/playerStorage';
import aiEvents, { EVENT, getEventMeta } from './services/events';
import throttle from '../utils/throttle';
const PLAYBACK_RATES = [0.5, 0.75, 1, 1.25, 1.5, 2, 3]; const PLAYBACK_RATES = [0.5, 0.75, 1, 1.25, 1.5, 2, 3];
@ -61,6 +63,9 @@ const soundProvider = (Player, events) => {
this.getFinalProps = this.getFinalProps.bind(this); this.getFinalProps = this.getFinalProps.bind(this);
this.onPlaying = this.onPlaying.bind(this); this.onPlaying = this.onPlaying.bind(this);
this.onFinishedPlaying = this.onFinishedPlaying.bind(this); this.onFinishedPlaying = this.onFinishedPlaying.bind(this);
this.aiEventTrackThrottled = throttle(options => {
aiEvents.eventTrack(options);
}, 60 * 1000);
} }
componentDidMount() { componentDidMount() {
@ -166,6 +171,14 @@ const soundProvider = (Player, events) => {
const { activeIndex } = this.state; const { activeIndex } = this.state;
const { playerId, rememberLastPosition } = this.props; const { playerId, rememberLastPosition } = this.props;
if (position > 60000) {
// Only start calling this after 1 minute into the track
this.aiEventTrackThrottled({
event: EVENT.PLAYING,
...getEventMeta(this.state, this.props),
});
}
this.setState( this.setState(
() => ({ duration, position }), () => ({ duration, position }),
() => { () => {
@ -173,8 +186,12 @@ const soundProvider = (Player, events) => {
events.onPlaying(this.getFinalProps()); events.onPlaying(this.getFinalProps());
} }
// Store last position every 5 seconds if (
if (playerId && rememberLastPosition && position % 5000 < 300) { playerId &&
rememberLastPosition &&
// Store last position on every 5th second or at the beginning of the track (tiny position num).
(position % 5000 < 300 || position < 350)
) {
playerStorage.set(playerId, { playerStorage.set(playerId, {
position, position,
activeIndex, activeIndex,
@ -187,7 +204,15 @@ const soundProvider = (Player, events) => {
onFinishedPlaying() { onFinishedPlaying() {
const { stopOnTrackFinish, delayBetweenTracks = 0 } = this.props; const { stopOnTrackFinish, delayBetweenTracks = 0 } = this.props;
const delayBetweenTracksMs = delayBetweenTracks * 1000; const delayBetweenTracksMs = delayBetweenTracks * 1000;
this.setState(() => ({ playStatus: Sound.status.STOPPED })); this.setState(
() => ({ playStatus: Sound.status.STOPPED }),
() => {
aiEvents.eventTrack({
event: EVENT.STOP,
...getEventMeta(this.state, this.props),
});
},
);
if (stopOnTrackFinish) { if (stopOnTrackFinish) {
return; return;
@ -228,7 +253,18 @@ const soundProvider = (Player, events) => {
} }
setPosition(position) { setPosition(position) {
this.setState(() => ({ position })); const currentPosition = this.state.position;
this.setState(
() => ({ position }),
() => {
aiEvents.eventTrack({
event: EVENT.SEEK,
...getEventMeta(this.state, this.props),
oldPosition: currentPosition,
});
},
);
} }
setTrackCycling(index, event) { setTrackCycling(index, event) {
@ -312,19 +348,44 @@ const soundProvider = (Player, events) => {
event.preventDefault(); event.preventDefault();
} }
const { repeatingTrackIndex, isMultiSoundDisabled } = this.state; const {
repeatingTrackIndex,
isMultiSoundDisabled,
playStatus,
} = this.state;
if (isMultiSoundDisabled) { if (isMultiSoundDisabled) {
window.soundManager.pauseAll(); window.soundManager.pauseAll();
} }
this.setState(() => ({ if (playStatus === Sound.status.PLAYING) {
activeIndex: index, aiEvents.eventTrack({
position: 0, event: EVENT.STOP,
playStatus: Sound.status.PLAYING, ...getEventMeta(this.state, this.props),
})); });
}
// Reset repating track index if the track is not the active one. this.setState(
() => ({
activeIndex: index,
position: 0,
playStatus: Sound.status.PLAYING,
}),
() => {
aiEvents.eventTrack({
event: EVENT.PLAY,
...getEventMeta(
{
...this.state,
duration: null,
},
this.props,
),
});
},
);
// Reset repeating track index if the track is not the active one.
if (index !== repeatingTrackIndex && repeatingTrackIndex != null) { if (index !== repeatingTrackIndex && repeatingTrackIndex != null) {
this.setTrackCycling(null); this.setTrackCycling(null);
} }
@ -338,7 +399,15 @@ const soundProvider = (Player, events) => {
const { playStatus } = this.state; const { playStatus } = this.state;
if (playStatus === Sound.status.PLAYING) { if (playStatus === Sound.status.PLAYING) {
this.setState(() => ({ playStatus: Sound.status.PAUSED })); this.setState(
() => ({ playStatus: Sound.status.PAUSED }),
() => {
aiEvents.eventTrack({
event: EVENT.PAUSE,
...getEventMeta(this.state, this.props),
});
},
);
} }
} }
@ -354,18 +423,29 @@ const soundProvider = (Player, events) => {
return; return;
} }
this.setState(({ playStatus, isMultiSoundDisabled }) => { this.setState(
if (playStatus !== Sound.status.PLAYING && isMultiSoundDisabled) { ({ playStatus, isMultiSoundDisabled }) => {
window.soundManager.pauseAll(); if (playStatus !== Sound.status.PLAYING && isMultiSoundDisabled) {
} window.soundManager.pauseAll();
}
return { return {
playStatus: playStatus:
playStatus === Sound.status.PLAYING playStatus === Sound.status.PLAYING
? Sound.status.PAUSED ? Sound.status.PAUSED
: Sound.status.PLAYING, : Sound.status.PLAYING,
}; };
}); },
() => {
aiEvents.eventTrack({
event:
this.state.playStatus === Sound.status.PLAYING
? EVENT.PLAY
: EVENT.PAUSE,
...getEventMeta(this.state, this.props),
});
},
);
} }
nextTrack() { nextTrack() {

View File

@ -0,0 +1,12 @@
/**
* Determines whether a given url is that of a stream or not.
*
* @param {string} url The url.
* @returns {boolean}
*/
const isStreamTrack = url => {
const extensions = ['.mp3', '.flac', '.amr', '.aac', '.oga', '.wav', '.wma'];
return !extensions.some(extension => url.includes(extension));
};
export default isStreamTrack;

View File

@ -0,0 +1,21 @@
/**
* Simple throttling function.
*
* @param {Function} fn The function to throttle.
* @param {number} limit The limit in milliseconds.
* @returns {(function(*): void)|*}
*/
const throttle = (fn, limit) => {
let waiting = false;
return function throttleCallback(...args) {
if (!waiting) {
fn.apply(this, args);
waiting = true;
setTimeout(() => {
waiting = false;
}, limit);
}
};
};
export default throttle;

View File

@ -255,18 +255,6 @@ $screen-xs-max: 320px !default;
} }
} }
.ai-waveform-bar {
display: block;
flex: 1;
position: relative;
height: 30px;
cursor: pointer;
}
.ai-waveform {
pointer-events: none;
}
.ai-track-time { .ai-track-time {
flex: none; flex: none;
font-size: 13px; font-size: 13px;

View File

@ -1011,6 +1011,13 @@
minimatch "^3.1.2" minimatch "^3.1.2"
strip-json-comments "^3.1.1" strip-json-comments "^3.1.1"
"@fingerprintjs/fingerprintjs@^3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@fingerprintjs/fingerprintjs/-/fingerprintjs-3.3.6.tgz#4c3f1726dc0cb10b915cfce78d9471b38cd809bd"
integrity sha512-Inh0OoFVzO2PLvrUF8RZhY9NVDdg9DJHQ5YlvXhrGtQxSPzy2smS3TWzLAi+zlHSJNHSvi+1zYayLen2lGxjdA==
dependencies:
tslib "^2.0.1"
"@humanwhocodes/config-array@^0.9.2": "@humanwhocodes/config-array@^0.9.2":
version "0.9.5" version "0.9.5"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7"
@ -5290,7 +5297,7 @@ tsconfig-paths@^3.14.1:
minimist "^1.2.6" minimist "^1.2.6"
strip-bom "^3.0.0" strip-bom "^3.0.0"
tslib@^2.0.3: tslib@^2.0.1, tslib@^2.0.3:
version "2.4.0" version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==

View File

@ -2,8 +2,8 @@
Contributors: cssigniterteam, anastis, silencerius, tsiger Contributors: cssigniterteam, anastis, silencerius, tsiger
Tags: audio, podcast, audio player, html5 player, mp3 player, music player, music, radio stream, radio player, sound player, player, podcast player Tags: audio, podcast, audio player, html5 player, mp3 player, music player, music, radio stream, radio player, sound player, player, podcast player
Requires at least: 5.0 Requires at least: 5.0
Tested up to: 6.0 Tested up to: 6.2
Stable tag: 1.9.0 Stable tag: 2.0.0
License: GPLv2 or later License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html License URI: http://www.gnu.org/licenses/gpl-2.0.html
@ -88,16 +88,19 @@ A [Pro version](https://www.cssigniter.com/plugins/audioigniter) is also availab
* Sync download URL with audio URL automatically * Sync download URL with audio URL automatically
* Standalone shortcode for single tracks (without the need to create a playlist) * Standalone shortcode for single tracks (without the need to create a playlist)
* Remember last played track and position * Remember last played track and position
* Per-playlist and per-track analytics
**PREMIUM SUPPORT** **PREMIUM SUPPORT**
You can expect the same level of support for both the free and pro version of our plugin. Average response time: 24 hours. You can expect the same level of support for both the free and pro version of our plugin. Average response time: 24 hours.
**JOIN OUR COMMUNITY**
Join our [Facebook group](https://www.facebook.com/groups/2601788933169108) to discuss new features and stay up to date on our latest releases.
== Installation == == Installation ==
1. Upload the plugin files to the `/wp-content/plugins/audioigniter` directory, or install the plugin through the WordPress plugins screen directly. 1. Upload the plugin files to the `/wp-content/plugins/audioigniter` directory, or install the plugin through the WordPress plugins screen directly.
2. Activate the plugin through the "Plugins" screen in WordPress 2. Activate the plugin through the "Plugins" screen in WordPress
3. In the WordPress admin dashboard you should see a new post type named "Playlists" 3. In the WordPress admin dashboard you should see a new top level menu named "AudioIgniter"
4. Navigate to the new Playlists post type and add your tracks! 4. Navigate to the Add New Playlist menu item and add your tracks!
== Screenshots == == Screenshots ==
1. The AudioIgniter player 1. The AudioIgniter player
@ -106,6 +109,14 @@ You can expect the same level of support for both the free and pro version of ou
== Changelog == == Changelog ==
= 2.0.0 =
* Added AudioIgniter top level menu.
* Fixed an issue where downloaded tracks would get the full URL as a filename, when the "Use the track URL as the download URL" was checked.
* Fixed an issue with the "Remember last position" the moment a track starts playing.
* Fixed an issue where the duration as a countdown would show weird format in some cases.
* Added base support so that the Shuffle button can now be displayed without being enabled/on by default (Pro feature).
* Added base support for AudioIgniter Analytics (Pro feature).
= 1.9.0 = = 1.9.0 =
* Fixed a JavaScript error in the admin when selecting an image without thumbnails. * Fixed a JavaScript error in the admin when selecting an image without thumbnails.
* Show the playlist shortcode metabox on the side. * Show the playlist shortcode metabox on the side.

View File

@ -1,11 +1,10 @@
<?php <?php
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) || if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ||
! WP_UNINSTALL_PLUGIN || ! WP_UNINSTALL_PLUGIN ||
dirname( WP_UNINSTALL_PLUGIN ) != dirname( plugin_basename( __FILE__ ) ) dirname( WP_UNINSTALL_PLUGIN ) !== dirname( plugin_basename( __FILE__ ) )
) { ) {
status_header( 404 ); status_header( 404 );
exit; exit;
} }
flush_rewrite_rules(); flush_rewrite_rules();