feat(#91): add multi color and palette support

This commit is contained in:
Benjamin Nussbaum 2025-11-22 16:43:33 +01:00
parent 61b9ff56e0
commit 568bd69fea
19 changed files with 1696 additions and 185 deletions

View file

@ -0,0 +1,38 @@
<?php
namespace Database\Factories;
use App\Models\DevicePalette;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\DevicePalette>
*/
class DevicePaletteFactory extends Factory
{
protected $model = DevicePalette::class;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'id' => 'test-' . $this->faker->unique()->slug(),
'name' => $this->faker->words(3, true),
'grays' => $this->faker->randomElement([2, 4, 16, 256]),
'colors' => $this->faker->optional()->passthrough([
'#FF0000',
'#00FF00',
'#0000FF',
'#FFFF00',
'#000000',
'#FFFFFF',
]),
'framework_class' => null,
'source' => 'api',
];
}
}

View file

@ -22,6 +22,7 @@ return new class extends Migration
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropUnique(['oidc_sub']);
$table->dropColumn('oidc_sub');
});
}

View file

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('device_palettes', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('description')->nullable();
$table->integer('grays');
$table->json('colors')->nullable();
$table->string('framework_class')->default('');
$table->string('source')->default('api');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('device_palettes');
}
};

View file

@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('device_models', function (Blueprint $table) {
$table->foreignId('palette_id')->nullable()->after('source')->constrained('device_palettes')->onDelete('set null');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('device_models', function (Blueprint $table) {
$table->dropForeign(['palette_id']);
$table->dropColumn('palette_id');
});
}
};

View file

@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('devices', function (Blueprint $table) {
$table->foreignId('palette_id')->nullable()->constrained('device_palettes')->onDelete('set null');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('devices', function (Blueprint $table) {
$table->dropForeign(['palette_id']);
$table->dropColumn('palette_id');
});
}
};

View file

@ -0,0 +1,124 @@
<?php
use App\Models\DeviceModel;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
// Seed palettes from hardcoded data
// name = identifier, description = human-readable name
$palettes = [
[
'name' => 'bw',
'description' => 'Black & White',
'grays' => 2,
'colors' => null,
'framework_class' => 'screen--1bit',
'source' => 'api',
],
[
'name' => 'gray-4',
'description' => '4 Grays',
'grays' => 4,
'colors' => null,
'framework_class' => 'screen--2bit',
'source' => 'api',
],
[
'name' => 'gray-16',
'description' => '16 Grays',
'grays' => 16,
'colors' => null,
'framework_class' => 'screen--4bit',
'source' => 'api',
],
[
'name' => 'gray-256',
'description' => '256 Grays',
'grays' => 256,
'colors' => null,
'framework_class' => 'screen--4bit',
'source' => 'api',
],
[
'name' => 'color-6a',
'description' => '6 Colors',
'grays' => 2,
'colors' => json_encode(['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#000000', '#FFFFFF']),
'framework_class' => '',
'source' => 'api',
],
[
'name' => 'color-7a',
'description' => '7 Colors',
'grays' => 2,
'colors' => json_encode(['#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FFA500']),
'framework_class' => '',
'source' => 'api',
],
];
$now = now();
$paletteIdMap = [];
foreach ($palettes as $paletteData) {
$paletteName = $paletteData['name'];
$paletteData['created_at'] = $now;
$paletteData['updated_at'] = $now;
DB::table('device_palettes')->updateOrInsert(
['name' => $paletteName],
$paletteData
);
// Get the ID of the palette (either newly created or existing)
$paletteRecord = DB::table('device_palettes')->where('name', $paletteName)->first();
$paletteIdMap[$paletteName] = $paletteRecord->id;
}
// Set default palette_id on DeviceModel based on first palette_ids entry
$models = [
['name' => 'og_png', 'palette_name' => 'bw'],
['name' => 'og_plus', 'palette_name' => 'gray-4'],
['name' => 'amazon_kindle_2024', 'palette_name' => 'gray-256'],
['name' => 'amazon_kindle_paperwhite_6th_gen', 'palette_name' => 'gray-256'],
['name' => 'amazon_kindle_paperwhite_7th_gen', 'palette_name' => 'gray-256'],
['name' => 'inkplate_10', 'palette_name' => 'gray-4'],
['name' => 'amazon_kindle_7', 'palette_name' => 'gray-256'],
['name' => 'inky_impression_7_3', 'palette_name' => 'color-7a'],
['name' => 'kobo_libra_2', 'palette_name' => 'gray-16'],
['name' => 'amazon_kindle_oasis_2', 'palette_name' => 'gray-256'],
['name' => 'kobo_aura_one', 'palette_name' => 'gray-16'],
['name' => 'kobo_aura_hd', 'palette_name' => 'gray-16'],
['name' => 'inky_impression_13_3', 'palette_name' => 'color-6a'],
['name' => 'm5_paper_s3', 'palette_name' => 'gray-16'],
['name' => 'amazon_kindle_scribe', 'palette_name' => 'gray-256'],
['name' => 'seeed_e1001', 'palette_name' => 'gray-4'],
['name' => 'seeed_e1002', 'palette_name' => 'gray-4'],
['name' => 'waveshare_4_26', 'palette_name' => 'gray-4'],
['name' => 'waveshare_7_5_bw', 'palette_name' => 'bw'],
];
foreach ($models as $modelData) {
$deviceModel = DeviceModel::where('name', $modelData['name'])->first();
if ($deviceModel && ! $deviceModel->palette_id && isset($paletteIdMap[$modelData['palette_name']])) {
$deviceModel->update(['palette_id' => $paletteIdMap[$modelData['palette_name']]]);
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Remove palette_id from device models but keep palettes
DeviceModel::query()->update(['palette_id' => null]);
}
};