mirror of
https://github.com/booklore-app/booklore.git
synced 2025-12-23 22:28:11 -05:00
Fix/hardcover api key per user (#1943)
* feat: add hardcover API key and sync settings to KoboSync and KoboUserSettings entities * feat(hardcover): enhance sync functionality to use per-user API keys - Updated HardcoverSyncService to utilize user-specific Hardcover API keys for syncing reading progress. - Modified syncProgressToHardcover method to accept userId, allowing for personalized sync settings. - Improved logging to include userId in sync operations for better traceability. - Adjusted KoboReadingStateService to pass userId when triggering sync to Hardcover. * feat(database): update kobo_location_source column size and add hardcover settings - Increased the size of the kobo_location_source column to accommodate longer location strings from Kobo devices. - Added new columns for hardcover API key and sync settings in the kobo_user_settings table to enhance user customization. * refactor(hardcover): update tests to use user-specific Kobo settings - Replaced AppSettingService with KoboSettingsService in HardcoverSyncServiceTest to utilize user-specific settings. - Modified syncProgressToHardcover method calls to include userId for personalized sync operations. - Added a new test case to handle scenarios where user settings are not found, ensuring robust error handling. --------- Co-authored-by: akiraslingshot <akiraslingshot@gmail.com>
This commit is contained in:
committed by
GitHub
parent
54108754f9
commit
32a1a2ac34
@@ -174,6 +174,82 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (koboSyncSettings.syncEnabled) {
|
||||
<div class="preferences-section">
|
||||
<div class="section-header">
|
||||
<h3 class="section-title">
|
||||
<i class="pi pi-book"></i>
|
||||
Hardcover Integration
|
||||
</h3>
|
||||
<p class="section-description">
|
||||
Sync your Kobo reading progress to your personal Hardcover account.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="settings-card">
|
||||
<div class="setting-item">
|
||||
<div class="setting-info">
|
||||
<div class="setting-label-row">
|
||||
<label class="setting-label">Sync Reading Progress to Hardcover</label>
|
||||
<p-toggle-switch
|
||||
id="hardcoverSyncEnabled"
|
||||
name="hardcoverSyncEnabled"
|
||||
[(ngModel)]="koboSyncSettings.hardcoverSyncEnabled"
|
||||
(ngModelChange)="onHardcoverSyncToggle()">
|
||||
</p-toggle-switch>
|
||||
</div>
|
||||
<p class="setting-description">
|
||||
When enabled, your reading progress from Kobo will be automatically synced to your Hardcover account.
|
||||
Each user can configure their own Hardcover account.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (koboSyncSettings.hardcoverSyncEnabled) {
|
||||
<div class="setting-item">
|
||||
<div class="setting-info">
|
||||
<div class="setting-label-row">
|
||||
<label class="setting-label">Hardcover API Key</label>
|
||||
<div class="token-input-group">
|
||||
<input
|
||||
pInputText
|
||||
id="hardcoverApiKey"
|
||||
[(ngModel)]="koboSyncSettings.hardcoverApiKey"
|
||||
[type]="showHardcoverApiKey ? 'text' : 'password'"
|
||||
name="hardcoverApiKey"
|
||||
class="token-input"
|
||||
placeholder="Enter your Hardcover API key"
|
||||
(blur)="onHardcoverApiKeyChange()"
|
||||
/>
|
||||
<p-button
|
||||
icon="pi pi-copy"
|
||||
outlined="true"
|
||||
severity="info"
|
||||
size="small"
|
||||
(onClick)="copyText(koboSyncSettings.hardcoverApiKey ?? '', 'API Key')"
|
||||
[disabled]="!koboSyncSettings.hardcoverApiKey">
|
||||
</p-button>
|
||||
<p-button
|
||||
[icon]="showHardcoverApiKey ? 'pi pi-eye-slash' : 'pi pi-eye'"
|
||||
outlined="true"
|
||||
severity="info"
|
||||
size="small"
|
||||
(onClick)="toggleShowHardcoverApiKey()">
|
||||
</p-button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="setting-description">
|
||||
Your personal Hardcover API key. Get it from
|
||||
<a href="https://hardcover.app/account/api" target="_blank" rel="noopener">hardcover.app/account/api</a>.
|
||||
This key is used only for syncing your reading progress and is not shared with other users.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (isAdmin) {
|
||||
<div class="preferences-section">
|
||||
<div class="section-header">
|
||||
|
||||
@@ -43,6 +43,7 @@ export class KoboSyncSettingsComponent implements OnInit, OnDestroy {
|
||||
isAdmin = false;
|
||||
credentialsSaved = false;
|
||||
showToken = false;
|
||||
showHardcoverApiKey = false;
|
||||
|
||||
koboSettings: KoboSettings = {
|
||||
convertToKepub: false,
|
||||
@@ -58,7 +59,9 @@ export class KoboSyncSettingsComponent implements OnInit, OnDestroy {
|
||||
syncEnabled: false,
|
||||
progressMarkAsReadingThreshold: 1,
|
||||
progressMarkAsFinishedThreshold: 99,
|
||||
autoAddToShelf: true
|
||||
autoAddToShelf: true,
|
||||
hardcoverApiKey: '',
|
||||
hardcoverSyncEnabled: false
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -119,6 +122,8 @@ export class KoboSyncSettingsComponent implements OnInit, OnDestroy {
|
||||
this.koboSyncSettings.progressMarkAsReadingThreshold = settings.progressMarkAsReadingThreshold ?? 1;
|
||||
this.koboSyncSettings.progressMarkAsFinishedThreshold = settings.progressMarkAsFinishedThreshold ?? 99;
|
||||
this.koboSyncSettings.autoAddToShelf = settings.autoAddToShelf ?? false;
|
||||
this.koboSyncSettings.hardcoverApiKey = settings.hardcoverApiKey ?? '';
|
||||
this.koboSyncSettings.hardcoverSyncEnabled = settings.hardcoverSyncEnabled ?? false;
|
||||
this.credentialsSaved = !!settings.token;
|
||||
},
|
||||
error: () => {
|
||||
@@ -167,6 +172,21 @@ export class KoboSyncSettingsComponent implements OnInit, OnDestroy {
|
||||
this.showToken = !this.showToken;
|
||||
}
|
||||
|
||||
toggleShowHardcoverApiKey() {
|
||||
this.showHardcoverApiKey = !this.showHardcoverApiKey;
|
||||
}
|
||||
|
||||
onHardcoverSyncToggle() {
|
||||
const message = this.koboSyncSettings.hardcoverSyncEnabled
|
||||
? 'Hardcover sync enabled'
|
||||
: 'Hardcover sync disabled';
|
||||
this.updateKoboSettings(message);
|
||||
}
|
||||
|
||||
onHardcoverApiKeyChange() {
|
||||
this.updateKoboSettings('Hardcover API key updated');
|
||||
}
|
||||
|
||||
confirmRegenerateToken() {
|
||||
this.confirmationService.confirm({
|
||||
message: 'This will generate a new token and invalidate the previous one. Continue?',
|
||||
|
||||
@@ -9,6 +9,8 @@ export interface KoboSyncSettings {
|
||||
progressMarkAsReadingThreshold?: number;
|
||||
progressMarkAsFinishedThreshold?: number;
|
||||
autoAddToShelf: boolean;
|
||||
hardcoverApiKey?: string;
|
||||
hardcoverSyncEnabled?: boolean;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
|
||||
Reference in New Issue
Block a user