mirror of
https://github.com/WenPai-org/git-embed-feicode.git
synced 2025-08-03 03:18:41 +08:00
Add site info and avatar display options to repo card
Introduces options to show site information and owner avatar in the repository card, including avatar size selection. Updates PHP, JS, and CSS to support new UI elements, avatar caching, and cache clearing via AJAX. Enhances visual presentation and user customization for embedded repository cards.
This commit is contained in:
parent
105d769c7f
commit
0c4746d0d3
3 changed files with 392 additions and 18 deletions
79
block.js
79
block.js
|
@ -67,6 +67,18 @@
|
|||
type: 'boolean',
|
||||
default: true
|
||||
},
|
||||
showAvatar: {
|
||||
type: 'boolean',
|
||||
default: true
|
||||
},
|
||||
showSiteInfo: {
|
||||
type: 'boolean',
|
||||
default: true
|
||||
},
|
||||
avatarSize: {
|
||||
type: 'string',
|
||||
default: 'medium'
|
||||
},
|
||||
cardStyle: {
|
||||
type: 'string',
|
||||
default: 'default'
|
||||
|
@ -86,7 +98,7 @@
|
|||
const {
|
||||
platform, owner, repo, showDescription, showStats, showLanguage,
|
||||
showActions, showViewButton, showCloneButton, showDownloadButton,
|
||||
cardStyle, buttonStyle, alignment
|
||||
showAvatar, showSiteInfo, avatarSize, cardStyle, buttonStyle, alignment
|
||||
} = attributes;
|
||||
|
||||
const [repoData, setRepoData] = useState(null);
|
||||
|
@ -167,24 +179,59 @@
|
|||
}
|
||||
|
||||
const cardClass = `git-embed-card${cardStyle !== 'default' ? ` git-embed-card-${cardStyle}` : ''}`;
|
||||
const avatarClass = `git-embed-avatar git-embed-avatar-${avatarSize}`;
|
||||
const downloadUrl = repoData.archive_url ?
|
||||
repoData.archive_url.replace('{archive_format}', 'zipball').replace('{/ref}', '/main') : '';
|
||||
|
||||
return el('div', { className: cardClass },
|
||||
el('div', { className: 'git-embed-header' },
|
||||
el('h3', { className: 'git-embed-title' },
|
||||
el('span', { className: 'dashicons dashicons-admin-links git-embed-repo-icon' }),
|
||||
showSiteInfo && repoData.site_info && el('div', { className: 'git-embed-site-info' },
|
||||
el('img', {
|
||||
src: repoData.site_info.favicon,
|
||||
alt: repoData.site_info.name,
|
||||
className: 'git-embed-site-favicon'
|
||||
}),
|
||||
el('span', { className: 'git-embed-site-name' },
|
||||
el('a', {
|
||||
href: repoData.html_url,
|
||||
href: repoData.site_info.url,
|
||||
target: '_blank',
|
||||
rel: 'noopener'
|
||||
}, repoData.full_name)
|
||||
}, repoData.site_info.name)
|
||||
)
|
||||
),
|
||||
|
||||
el('div', { className: 'git-embed-header' },
|
||||
el('div', { className: 'git-embed-title-section' },
|
||||
showAvatar && repoData.owner && el('img', {
|
||||
src: repoData.owner.avatar_url,
|
||||
alt: repoData.owner.login,
|
||||
className: avatarClass
|
||||
}),
|
||||
el('div', { className: 'git-embed-title-content' },
|
||||
el('h3', { className: 'git-embed-title' },
|
||||
el('span', { className: 'dashicons dashicons-admin-links git-embed-repo-icon' }),
|
||||
el('a', {
|
||||
href: repoData.html_url,
|
||||
target: '_blank',
|
||||
rel: 'noopener'
|
||||
}, repoData.full_name)
|
||||
),
|
||||
showAvatar && repoData.owner && el('div', { className: 'git-embed-owner-info' },
|
||||
el('span', { className: 'git-embed-owner-type' }, repoData.owner.type),
|
||||
el('a', {
|
||||
href: repoData.owner.html_url,
|
||||
target: '_blank',
|
||||
rel: 'noopener',
|
||||
className: 'git-embed-owner-link'
|
||||
}, `@${repoData.owner.login}`)
|
||||
)
|
||||
)
|
||||
),
|
||||
showLanguage && repoData.language && el('span', { className: 'git-embed-language' },
|
||||
el('span', { className: 'dashicons dashicons-editor-code' }),
|
||||
repoData.language
|
||||
)
|
||||
),
|
||||
|
||||
showDescription && repoData.description &&
|
||||
el('p', { className: 'git-embed-description' },
|
||||
el('span', { className: 'dashicons dashicons-text-page' }),
|
||||
|
@ -279,6 +326,26 @@
|
|||
title: __('Display Options', 'git-embed-feicode'),
|
||||
initialOpen: false
|
||||
},
|
||||
el(ToggleControl, {
|
||||
label: __('Show Site Information', 'git-embed-feicode'),
|
||||
checked: showSiteInfo,
|
||||
onChange: (value) => setAttributes({ showSiteInfo: value })
|
||||
}),
|
||||
el(ToggleControl, {
|
||||
label: __('Show Owner Avatar', 'git-embed-feicode'),
|
||||
checked: showAvatar,
|
||||
onChange: (value) => setAttributes({ showAvatar: value })
|
||||
}),
|
||||
showAvatar && el(SelectControl, {
|
||||
label: __('Avatar Size', 'git-embed-feicode'),
|
||||
value: avatarSize,
|
||||
options: [
|
||||
{ label: 'Small', value: 'small' },
|
||||
{ label: 'Medium', value: 'medium' },
|
||||
{ label: 'Large', value: 'large' }
|
||||
],
|
||||
onChange: (value) => setAttributes({ avatarSize: value })
|
||||
}),
|
||||
el(ToggleControl, {
|
||||
label: __('Show Description', 'git-embed-feicode'),
|
||||
checked: showDescription,
|
||||
|
|
|
@ -23,6 +23,8 @@ class GitEmbedFeiCode {
|
|||
add_action('init', [$this, 'init']);
|
||||
add_action('wp_ajax_git_embed_fetch', [$this, 'ajax_fetch_repo']);
|
||||
add_action('wp_ajax_nopriv_git_embed_fetch', [$this, 'ajax_fetch_repo']);
|
||||
add_action('wp_ajax_git_embed_clear_cache', [$this, 'ajax_clear_cache']);
|
||||
register_deactivation_hook(__FILE__, [$this, 'clear_all_cache']);
|
||||
}
|
||||
|
||||
public function init(): void {
|
||||
|
@ -85,6 +87,18 @@ class GitEmbedFeiCode {
|
|||
'type' => 'string',
|
||||
'default' => 'primary'
|
||||
],
|
||||
'showAvatar' => [
|
||||
'type' => 'boolean',
|
||||
'default' => true
|
||||
],
|
||||
'showSiteInfo' => [
|
||||
'type' => 'boolean',
|
||||
'default' => true
|
||||
],
|
||||
'avatarSize' => [
|
||||
'type' => 'string',
|
||||
'default' => 'medium'
|
||||
],
|
||||
'alignment' => [
|
||||
'type' => 'string',
|
||||
'default' => 'none'
|
||||
|
@ -108,7 +122,8 @@ class GitEmbedFeiCode {
|
|||
|
||||
wp_localize_script('git-embed-feicode-editor', 'gitEmbedAjax', [
|
||||
'url' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('git_embed_nonce')
|
||||
'nonce' => wp_create_nonce('git_embed_nonce'),
|
||||
'cache_nonce' => wp_create_nonce('git_embed_cache_nonce')
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -144,9 +159,10 @@ class GitEmbedFeiCode {
|
|||
|
||||
$url = "https://api.github.com/repos/{$owner}/{$repo}";
|
||||
$response = wp_remote_get($url, [
|
||||
'timeout' => 10,
|
||||
'timeout' => 15,
|
||||
'headers' => [
|
||||
'User-Agent' => 'Git-Embed-FeiCode/1.0'
|
||||
'User-Agent' => 'Git-Embed-FeiCode/1.0',
|
||||
'Accept' => 'application/vnd.github.v3+json'
|
||||
]
|
||||
]);
|
||||
|
||||
|
@ -170,14 +186,51 @@ class GitEmbedFeiCode {
|
|||
'forks_count' => $data['forks_count'],
|
||||
'open_issues_count' => $data['open_issues_count'],
|
||||
'clone_url' => $data['clone_url'],
|
||||
'archive_url' => $data['archive_url']
|
||||
'archive_url' => $data['archive_url'],
|
||||
'owner' => [
|
||||
'login' => $data['owner']['login'],
|
||||
'avatar_url' => $data['owner']['avatar_url'],
|
||||
'html_url' => $data['owner']['html_url'],
|
||||
'type' => $data['owner']['type']
|
||||
],
|
||||
'site_info' => [
|
||||
'name' => 'GitHub',
|
||||
'url' => 'https://github.com',
|
||||
'favicon' => 'https://github.com/favicon.ico',
|
||||
'color' => '#24292f'
|
||||
]
|
||||
];
|
||||
|
||||
set_transient($cache_key, $repo_data, HOUR_IN_SECONDS);
|
||||
set_transient($cache_key, $repo_data, DAY_IN_SECONDS);
|
||||
|
||||
$this->cache_avatar($repo_data['owner']['avatar_url']);
|
||||
|
||||
return $repo_data;
|
||||
}
|
||||
|
||||
private function cache_avatar(string $avatar_url): void {
|
||||
if (empty($avatar_url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cache_key = 'git_embed_avatar_' . md5($avatar_url);
|
||||
|
||||
if (get_transient($cache_key) !== false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$response = wp_remote_get($avatar_url, [
|
||||
'timeout' => 10,
|
||||
'headers' => [
|
||||
'User-Agent' => 'Git-Embed-FeiCode/1.0'
|
||||
]
|
||||
]);
|
||||
|
||||
if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
|
||||
set_transient($cache_key, true, WEEK_IN_SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
private function render_repository_card(array $repo_data, array $attributes): string {
|
||||
$show_description = $attributes['showDescription'] ?? true;
|
||||
$show_stats = $attributes['showStats'] ?? true;
|
||||
|
@ -186,12 +239,16 @@ class GitEmbedFeiCode {
|
|||
$show_view_button = $attributes['showViewButton'] ?? true;
|
||||
$show_clone_button = $attributes['showCloneButton'] ?? true;
|
||||
$show_download_button = $attributes['showDownloadButton'] ?? true;
|
||||
$show_avatar = $attributes['showAvatar'] ?? true;
|
||||
$show_site_info = $attributes['showSiteInfo'] ?? true;
|
||||
$avatar_size = $attributes['avatarSize'] ?? 'medium';
|
||||
$card_style = $attributes['cardStyle'] ?? 'default';
|
||||
$button_style = $attributes['buttonStyle'] ?? 'primary';
|
||||
$alignment = $attributes['alignment'] ?? 'none';
|
||||
|
||||
$align_class = $alignment !== 'none' ? " align{$alignment}" : '';
|
||||
$card_class = $card_style !== 'default' ? " git-embed-card-{$card_style}" : '';
|
||||
$avatar_class = "git-embed-avatar-{$avatar_size}";
|
||||
|
||||
$download_url = str_replace('{archive_format}', 'zipball', $repo_data['archive_url']);
|
||||
$download_url = str_replace('{/ref}', '/main', $download_url);
|
||||
|
@ -200,13 +257,50 @@ class GitEmbedFeiCode {
|
|||
?>
|
||||
<div class="wp-block-git-embed-feicode-repository<?php echo esc_attr($align_class); ?>">
|
||||
<div class="git-embed-card<?php echo esc_attr($card_class); ?>">
|
||||
<?php if ($show_site_info): ?>
|
||||
<div class="git-embed-site-info">
|
||||
<img src="<?php echo esc_url($repo_data['site_info']['favicon']); ?>"
|
||||
alt="<?php echo esc_attr($repo_data['site_info']['name']); ?>"
|
||||
class="git-embed-site-favicon"
|
||||
loading="lazy">
|
||||
<span class="git-embed-site-name">
|
||||
<a href="<?php echo esc_url($repo_data['site_info']['url']); ?>"
|
||||
target="_blank" rel="noopener">
|
||||
<?php echo esc_html($repo_data['site_info']['name']); ?>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="git-embed-header">
|
||||
<h3 class="git-embed-title">
|
||||
<span class="dashicons dashicons-admin-links git-embed-repo-icon"></span>
|
||||
<a href="<?php echo esc_url($repo_data['html_url']); ?>" target="_blank" rel="noopener">
|
||||
<?php echo esc_html($repo_data['full_name']); ?>
|
||||
</a>
|
||||
</h3>
|
||||
<div class="git-embed-title-section">
|
||||
<?php if ($show_avatar): ?>
|
||||
<img src="<?php echo esc_url($repo_data['owner']['avatar_url']); ?>"
|
||||
alt="<?php echo esc_attr($repo_data['owner']['login']); ?>"
|
||||
class="git-embed-avatar <?php echo esc_attr($avatar_class); ?>"
|
||||
loading="lazy">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="git-embed-title-content">
|
||||
<h3 class="git-embed-title">
|
||||
<span class="dashicons dashicons-admin-links git-embed-repo-icon"></span>
|
||||
<a href="<?php echo esc_url($repo_data['html_url']); ?>" target="_blank" rel="noopener">
|
||||
<?php echo esc_html($repo_data['full_name']); ?>
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
<?php if ($show_avatar): ?>
|
||||
<div class="git-embed-owner-info">
|
||||
<span class="git-embed-owner-type"><?php echo esc_html($repo_data['owner']['type']); ?></span>
|
||||
<a href="<?php echo esc_url($repo_data['owner']['html_url']); ?>"
|
||||
target="_blank" rel="noopener" class="git-embed-owner-link">
|
||||
@<?php echo esc_html($repo_data['owner']['login']); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($show_language && $repo_data['language']): ?>
|
||||
<span class="git-embed-language">
|
||||
<span class="dashicons dashicons-editor-code"></span>
|
||||
|
@ -334,6 +428,61 @@ class GitEmbedFeiCode {
|
|||
wp_send_json_success($repo_data);
|
||||
}
|
||||
|
||||
public function ajax_clear_cache(): void {
|
||||
check_ajax_referer('git_embed_cache_nonce', 'nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error('Insufficient permissions');
|
||||
}
|
||||
|
||||
$platform = sanitize_text_field($_POST['platform'] ?? '');
|
||||
$owner = sanitize_text_field($_POST['owner'] ?? '');
|
||||
$repo = sanitize_text_field($_POST['repo'] ?? '');
|
||||
|
||||
if (empty($owner) || empty($repo)) {
|
||||
wp_send_json_error('Repository information required');
|
||||
}
|
||||
|
||||
$this->clear_repository_cache($platform, $owner, $repo);
|
||||
|
||||
wp_send_json_success('Cache cleared successfully');
|
||||
}
|
||||
|
||||
private function clear_repository_cache(string $platform, string $owner, string $repo): void {
|
||||
$cache_key = "git_embed_{$platform}_{$owner}_{$repo}";
|
||||
delete_transient($cache_key);
|
||||
|
||||
global $wpdb;
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
|
||||
$wpdb->esc_like('_transient_git_embed_avatar_') . '%'
|
||||
)
|
||||
);
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
|
||||
$wpdb->esc_like('_transient_timeout_git_embed_avatar_') . '%'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function clear_all_cache(): void {
|
||||
global $wpdb;
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
|
||||
$wpdb->esc_like('_transient_git_embed_') . '%'
|
||||
)
|
||||
);
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
|
||||
$wpdb->esc_like('_transient_timeout_git_embed_') . '%'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function load_textdomain(): void {
|
||||
load_plugin_textdomain(
|
||||
'git-embed-feicode',
|
||||
|
|
160
style.css
160
style.css
|
@ -58,13 +58,108 @@
|
|||
border: none;
|
||||
}
|
||||
|
||||
.git-embed-header {
|
||||
.git-embed-site-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid #e1e4e8;
|
||||
}
|
||||
|
||||
.git-embed-site-favicon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.git-embed-site-name {
|
||||
font-size: 12px;
|
||||
color: #656d76;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.git-embed-site-name a {
|
||||
color: #656d76;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.git-embed-site-name a:hover {
|
||||
color: #0969da;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.git-embed-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.git-embed-title-section {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.git-embed-title-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.git-embed-avatar {
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
border: 2px solid #e1e4e8;
|
||||
}
|
||||
|
||||
.git-embed-avatar-small {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.git-embed-avatar-medium {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.git-embed-avatar-large {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.git-embed-owner-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.git-embed-owner-type {
|
||||
background: #f1f8ff;
|
||||
color: #0969da;
|
||||
padding: 2px 6px;
|
||||
border-radius: 12px;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.git-embed-owner-link {
|
||||
color: #656d76;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.git-embed-owner-link:hover {
|
||||
color: #0969da;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.git-embed-title {
|
||||
|
@ -299,9 +394,35 @@
|
|||
padding: 16px;
|
||||
}
|
||||
|
||||
.git-embed-site-info {
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.git-embed-title-section {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.git-embed-avatar-large {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.git-embed-avatar-medium {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.git-embed-owner-info {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.git-embed-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.git-embed-stats {
|
||||
|
@ -332,6 +453,19 @@
|
|||
font-size: 16px;
|
||||
}
|
||||
|
||||
.git-embed-title-section {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.git-embed-avatar {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.git-embed-owner-info {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.git-embed-actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
@ -345,6 +479,10 @@
|
|||
text-align: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.git-embed-site-info {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.wp-block[data-type="git-embed-feicode/repository"] {
|
||||
|
@ -365,4 +503,24 @@
|
|||
|
||||
.components-panel__body .components-select-control:disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.git-embed-card img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.git-embed-site-favicon,
|
||||
.git-embed-avatar {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
}
|
||||
|
||||
.git-embed-card .git-embed-avatar:hover {
|
||||
transform: scale(1.05);
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.git-embed-owner-type:empty {
|
||||
display: none;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue