diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 5b18d3030..2a3ce59b3 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -10,6 +10,7 @@ class DashboardController < ActionController::Base TERMS_URL BRAND_URL BRAND_NAME + BRAND_COLOR PRIVACY_URL DISPLAY_MANIFEST CREATE_NEW_ACCOUNT_FROM_DASHBOARD diff --git a/app/controllers/manifest_controller.rb b/app/controllers/manifest_controller.rb new file mode 100644 index 000000000..31115a0c9 --- /dev/null +++ b/app/controllers/manifest_controller.rb @@ -0,0 +1,35 @@ +class ManifestController < ApplicationController + PNG_MIME = 'image/png'.freeze + SVG_MIME = 'image/svg+xml'.freeze + + def show + config = GlobalConfig.get('INSTALLATION_NAME', 'LOGO_THUMBNAIL', 'BRAND_COLOR') + installation_name = config['INSTALLATION_NAME'].presence || 'Chatwoot' + logo = config['LOGO_THUMBNAIL'].presence || '/brand-assets/logo_thumbnail.svg' + brand_color = config['BRAND_COLOR'].presence || '#1f93ff' + icon_type = svg?(logo) ? SVG_MIME : PNG_MIME + + expires_in 1.hour, public: true + render json: { + name: installation_name, + short_name: installation_name, + id: '/', + start_url: '/', + display: 'standalone', + background_color: brand_color, + theme_color: brand_color, + icons: [ + { src: logo, sizes: '192x192', type: icon_type, purpose: 'any maskable' }, + { src: logo, sizes: '512x512', type: icon_type, purpose: 'any maskable' } + ] + }, content_type: 'application/manifest+json' + end + + private + + def svg?(url) + File.extname(URI.parse(url).path).casecmp('.svg').zero? + rescue URI::InvalidURIError + false + end +end diff --git a/app/views/layouts/vueapp.html.erb b/app/views/layouts/vueapp.html.erb index 12a3bcd51..29ccad9b0 100644 --- a/app/views/layouts/vueapp.html.erb +++ b/app/views/layouts/vueapp.html.erb @@ -6,10 +6,15 @@ + + + + + + <% if @global_config['DISPLAY_MANIFEST'] %> - + - <% if ENV['IOS_APP_IDENTIFIER'].present? %> '> @@ -27,7 +32,6 @@ - <% end %> <%= csrf_meta_tags %> diff --git a/config/installation_config.yml b/config/installation_config.yml index 884dd2e58..72bb866c0 100644 --- a/config/installation_config.yml +++ b/config/installation_config.yml @@ -42,6 +42,10 @@ value: 'Chatwoot' display_title: 'Brand Name' description: 'The name that would be used in emails and the widget' +- name: BRAND_COLOR + value: '#1f93ff' + display_title: 'Brand Color' + description: 'Hex color used for PWA theme/tile color (example: #1f93ff). For reliable Android PWA install prompts, pair with a 192x192 and 512x512 PNG logo thumbnail.' - name: TERMS_URL value: 'https://www.chatwoot.com/terms-of-service' display_title: 'Terms URL' diff --git a/config/routes.rb b/config/routes.rb index e4d1f5e0b..19dc35708 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -669,6 +669,7 @@ Rails.application.routes.draw do get 'notion/callback', to: 'notion/callbacks#show' # ---------------------------------------------------------------------- # Routes for external service verifications + get '/manifest.json' => 'manifest#show' get '.well-known/assetlinks.json' => 'android_app#assetlinks' get '.well-known/apple-app-site-association' => 'apple_app#site_association' get '.well-known/microsoft-identity-association.json' => 'microsoft#identity_association' diff --git a/enterprise/app/controllers/enterprise/super_admin/app_configs_controller.rb b/enterprise/app/controllers/enterprise/super_admin/app_configs_controller.rb index f91f12708..3ca637ac7 100644 --- a/enterprise/app/controllers/enterprise/super_admin/app_configs_controller.rb +++ b/enterprise/app/controllers/enterprise/super_admin/app_configs_controller.rb @@ -24,6 +24,7 @@ module Enterprise::SuperAdmin::AppConfigsController LOGO LOGO_DARK BRAND_NAME + BRAND_COLOR INSTALLATION_NAME BRAND_URL WIDGET_BRAND_URL diff --git a/public/manifest.json b/public/manifest.json deleted file mode 100644 index 9f4bfa937..000000000 --- a/public/manifest.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "Chatwoot", - "short_name": "Chatwoot", - "icons": [{ - "src": "\/android-icon-36x36.png", - "sizes": "36x36", - "type": "image\/png", - "density": "0.75" - }, - { - "src": "\/android-icon-48x48.png", - "sizes": "48x48", - "type": "image\/png", - "density": "1.0" - }, - { - "src": "\/android-icon-72x72.png", - "sizes": "72x72", - "type": "image\/png", - "density": "1.5" - }, - { - "src": "\/android-icon-96x96.png", - "sizes": "96x96", - "type": "image\/png", - "density": "2.0" - }, - { - "src": "\/android-icon-144x144.png", - "sizes": "144x144", - "type": "image\/png", - "density": "3.0" - }, - { - "src": "\/android-icon-192x192.png", - "sizes": "192x192", - "type": "image\/png", - "density": "4.0" - }], - "start_url": "/", - "display": "standalone", - "background_color": "#1f93ff", - "theme_color": "#1f93fe" -}