From 0b5cc452ef59db87d6872572e3de6d55e8d536d3 Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Wed, 7 Jan 2026 14:30:52 +0700 Subject: [PATCH] Add custom database type icons throughout UI Replaces generic SF Symbols with official database logos: - MySQL: dolphin logo - MariaDB: seal logo - PostgreSQL: elephant logo - SQLite: feather logo Changes: - Add SVG icon assets to Assets.xcassets with template rendering - Update DatabaseType.iconName to return asset names - Update all Image() calls to use template rendering mode - Apply consistent icon sizing and color tinting Icons now appear in: - Welcome screen connection list - Sidebar connection header - Toolbar connection status All icons respect custom connection colors and work in light/dark mode. --- .../mariadb-icon.imageset/Contents.json | 16 ++++++++++++++++ .../mariadb-icon.imageset/mariadb.svg | 1 + .../mysql-icon.imageset/Contents.json | 16 ++++++++++++++++ .../mysql-icon.imageset/mysql.svg | 1 + .../postgresql-icon.imageset/Contents.json | 16 ++++++++++++++++ .../postgresql-icon.imageset/postgresql.svg | 1 + .../sqlite-icon.imageset/Contents.json | 16 ++++++++++++++++ .../sqlite-icon.imageset/sqlite.svg | 1 + TablePro/Models/DatabaseConnection.swift | 12 +++++++----- .../Connection/ConnectionSidebarHeader.swift | 9 ++++++--- .../Views/Toolbar/ConnectionStatusView.swift | 3 ++- TablePro/Views/WelcomeWindowView.swift | 10 ++++++---- 12 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 TablePro/Assets.xcassets/mariadb-icon.imageset/Contents.json create mode 100644 TablePro/Assets.xcassets/mariadb-icon.imageset/mariadb.svg create mode 100644 TablePro/Assets.xcassets/mysql-icon.imageset/Contents.json create mode 100644 TablePro/Assets.xcassets/mysql-icon.imageset/mysql.svg create mode 100644 TablePro/Assets.xcassets/postgresql-icon.imageset/Contents.json create mode 100644 TablePro/Assets.xcassets/postgresql-icon.imageset/postgresql.svg create mode 100644 TablePro/Assets.xcassets/sqlite-icon.imageset/Contents.json create mode 100644 TablePro/Assets.xcassets/sqlite-icon.imageset/sqlite.svg diff --git a/TablePro/Assets.xcassets/mariadb-icon.imageset/Contents.json b/TablePro/Assets.xcassets/mariadb-icon.imageset/Contents.json new file mode 100644 index 000000000..e79abfbfc --- /dev/null +++ b/TablePro/Assets.xcassets/mariadb-icon.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "mariadb.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/TablePro/Assets.xcassets/mariadb-icon.imageset/mariadb.svg b/TablePro/Assets.xcassets/mariadb-icon.imageset/mariadb.svg new file mode 100644 index 000000000..4be3fb584 --- /dev/null +++ b/TablePro/Assets.xcassets/mariadb-icon.imageset/mariadb.svg @@ -0,0 +1 @@ +MariaDB diff --git a/TablePro/Assets.xcassets/mysql-icon.imageset/Contents.json b/TablePro/Assets.xcassets/mysql-icon.imageset/Contents.json new file mode 100644 index 000000000..e07290098 --- /dev/null +++ b/TablePro/Assets.xcassets/mysql-icon.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "mysql.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/TablePro/Assets.xcassets/mysql-icon.imageset/mysql.svg b/TablePro/Assets.xcassets/mysql-icon.imageset/mysql.svg new file mode 100644 index 000000000..c5297b052 --- /dev/null +++ b/TablePro/Assets.xcassets/mysql-icon.imageset/mysql.svg @@ -0,0 +1 @@ +MySQL diff --git a/TablePro/Assets.xcassets/postgresql-icon.imageset/Contents.json b/TablePro/Assets.xcassets/postgresql-icon.imageset/Contents.json new file mode 100644 index 000000000..0c0410ae2 --- /dev/null +++ b/TablePro/Assets.xcassets/postgresql-icon.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "postgresql.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/TablePro/Assets.xcassets/postgresql-icon.imageset/postgresql.svg b/TablePro/Assets.xcassets/postgresql-icon.imageset/postgresql.svg new file mode 100644 index 000000000..d7b2b8d77 --- /dev/null +++ b/TablePro/Assets.xcassets/postgresql-icon.imageset/postgresql.svg @@ -0,0 +1 @@ +PostgreSQL diff --git a/TablePro/Assets.xcassets/sqlite-icon.imageset/Contents.json b/TablePro/Assets.xcassets/sqlite-icon.imageset/Contents.json new file mode 100644 index 000000000..87fbba8da --- /dev/null +++ b/TablePro/Assets.xcassets/sqlite-icon.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "filename" : "sqlite.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "template" + } +} diff --git a/TablePro/Assets.xcassets/sqlite-icon.imageset/sqlite.svg b/TablePro/Assets.xcassets/sqlite-icon.imageset/sqlite.svg new file mode 100644 index 000000000..9098d90f5 --- /dev/null +++ b/TablePro/Assets.xcassets/sqlite-icon.imageset/sqlite.svg @@ -0,0 +1 @@ +SQLite diff --git a/TablePro/Models/DatabaseConnection.swift b/TablePro/Models/DatabaseConnection.swift index 8e52ca86c..7068936cb 100644 --- a/TablePro/Models/DatabaseConnection.swift +++ b/TablePro/Models/DatabaseConnection.swift @@ -60,15 +60,17 @@ enum DatabaseType: String, CaseIterable, Identifiable, Codable { var id: String { rawValue } - /// SF Symbol name for each database type + /// Asset name for each database type icon var iconName: String { switch self { - case .mysql, .mariadb: - return "cylinder.split.1x2.fill" + case .mysql: + return "mysql-icon" + case .mariadb: + return "mariadb-icon" case .postgresql: - return "server.rack" + return "postgresql-icon" case .sqlite: - return "doc.fill" + return "sqlite-icon" } } diff --git a/TablePro/Views/Connection/ConnectionSidebarHeader.swift b/TablePro/Views/Connection/ConnectionSidebarHeader.swift index 97738af24..173489e38 100644 --- a/TablePro/Views/Connection/ConnectionSidebarHeader.swift +++ b/TablePro/Views/Connection/ConnectionSidebarHeader.swift @@ -34,7 +34,8 @@ struct ConnectionSidebarHeader: View { onSelectSession(session.id) }) { HStack { - Image(systemName: session.connection.type.iconName) + Image(session.connection.type.iconName) + .renderingMode(.template) .foregroundStyle(session.connection.displayColor) Text(session.connection.database) @@ -66,7 +67,8 @@ struct ConnectionSidebarHeader: View { onOpenConnection(connection) }) { HStack { - Image(systemName: connection.type.iconName) + Image(connection.type.iconName) + .renderingMode(.template) .foregroundStyle(connection.displayColor) Text(connection.name) @@ -88,7 +90,8 @@ struct ConnectionSidebarHeader: View { HStack(spacing: 8) { // Database icon if let session = currentSession { - Image(systemName: session.connection.type.iconName) + Image(session.connection.type.iconName) + .renderingMode(.template) .font(.system(size: DesignConstants.IconSize.medium)) .foregroundStyle(session.connection.displayColor) } else { diff --git a/TablePro/Views/Toolbar/ConnectionStatusView.swift b/TablePro/Views/Toolbar/ConnectionStatusView.swift index 95c216bd0..af6c65fc5 100644 --- a/TablePro/Views/Toolbar/ConnectionStatusView.swift +++ b/TablePro/Views/Toolbar/ConnectionStatusView.swift @@ -46,7 +46,8 @@ struct ConnectionStatusView: View { private var databaseInfoSection: some View { HStack(spacing: 6) { // Database type icon - Image(systemName: databaseType.iconName) + Image(databaseType.iconName) + .renderingMode(.template) .font(.system(size: DesignConstants.IconSize.default)) .foregroundStyle(displayColor) diff --git a/TablePro/Views/WelcomeWindowView.swift b/TablePro/Views/WelcomeWindowView.swift index 847d5a440..914f6c32e 100644 --- a/TablePro/Views/WelcomeWindowView.swift +++ b/TablePro/Views/WelcomeWindowView.swift @@ -359,10 +359,12 @@ private struct ConnectionRow: View { var body: some View { HStack(spacing: 12) { - // Database type indicator - uses custom color if set - Circle() - .fill(connection.displayColor) - .frame(width: DesignConstants.IconSize.statusDot + 2, height: DesignConstants.IconSize.statusDot + 2) + // Database type icon + Image(connection.type.iconName) + .renderingMode(.template) + .font(.system(size: DesignConstants.IconSize.medium)) + .foregroundStyle(connection.displayColor) + .frame(width: DesignConstants.IconSize.medium, height: DesignConstants.IconSize.medium) // Connection info VStack(alignment: .leading, spacing: 2) {