Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow admins to configure instance favicon and logo #30040

Merged
merged 14 commits into from May 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 35 additions & 0 deletions app/lib/icon_generator.rb
@@ -0,0 +1,35 @@
# frozen_string_literal: true

module IconGenerator
extend self

def generate_favicons(source_path, output_dest, sizes)
favicons = generate_icons(source_path, output_dest, sizes, 'favicon')

Check warning on line 7 in app/lib/icon_generator.rb

View check run for this annotation

Codecov / codecov/patch

app/lib/icon_generator.rb#L7

Added line #L7 was not covered by tests

convert.run(input: favicons, output: Rails.public_path.join('favicon.ico'))

Check warning on line 9 in app/lib/icon_generator.rb

View check run for this annotation

Codecov / codecov/patch

app/lib/icon_generator.rb#L9

Added line #L9 was not covered by tests
renchap marked this conversation as resolved.
Show resolved Hide resolved
end

def generate_app_icons(source_path, output_dest, sizes, prefix)
generate_icons(source_path, output_dest, sizes, prefix)

Check warning on line 13 in app/lib/icon_generator.rb

View check run for this annotation

Codecov / codecov/patch

app/lib/icon_generator.rb#L13

Added line #L13 was not covered by tests
end

private

def generate_icons(source_path, output_dest, sizes, prefix)
icon_paths = []
sizes.each do |size|
output_path = output_dest.join("#{prefix}-#{size}x#{size}.png")
icon_paths << output_path
rsvg_convert.run(size: size, input: source_path, output: output_path)

Check warning on line 23 in app/lib/icon_generator.rb

View check run for this annotation

Codecov / codecov/patch

app/lib/icon_generator.rb#L19-L23

Added lines #L19 - L23 were not covered by tests
end
icon_paths

Check warning on line 25 in app/lib/icon_generator.rb

View check run for this annotation

Codecov / codecov/patch

app/lib/icon_generator.rb#L25

Added line #L25 was not covered by tests
end

def rsvg_convert
@rsvg_convert ||= Terrapin::CommandLine.new('rsvg-convert', '-w :size -h :size --keep-aspect-ratio :input -o :output')

Check warning on line 29 in app/lib/icon_generator.rb

View check run for this annotation

Codecov / codecov/patch

app/lib/icon_generator.rb#L29

Added line #L29 was not covered by tests
end

def convert
@convert ||= Terrapin::CommandLine.new('convert', ':input :output', environment: { 'MAGICK_CONFIGURE_PATH' => nil })

Check warning on line 33 in app/lib/icon_generator.rb

View check run for this annotation

Codecov / codecov/patch

app/lib/icon_generator.rb#L33

Added line #L33 was not covered by tests
end
end
12 changes: 12 additions & 0 deletions app/views/admin/settings/appearance/show.html.haml
Expand Up @@ -23,6 +23,18 @@
input_html: { rows: 8 },
wrapper: :with_block_label

.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :favicon,
as: :file,
wrapper: :with_block_label

.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :app_icon,
as: :file,
wrapper: :with_block_label

.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :mascot,
Expand Down
2 changes: 2 additions & 0 deletions config/locales/simple_form.en-GB.yml
Expand Up @@ -77,11 +77,13 @@ en-GB:
warn: Hide the filtered content behind a warning mentioning the filter's title
form_admin_settings:
activity_api_enabled: Counts of locally published posts, active users, and new registrations in weekly buckets
app_icon: Overrides the default app icon on mobile devices with a custom icon.
backups_retention_period: Keep generated user archives for the specified number of days.
bootstrap_timeline_accounts: These accounts will be pinned to the top of new users' follow recommendations.
closed_registrations_message: Displayed when sign-ups are closed
content_cache_retention_period: Posts from other servers will be deleted after the specified number of days when set to a positive value. This may be irreversible.
custom_css: You can apply custom styles on the web version of Mastodon.
favicon: Overrides the default Mastodon favicon with a custom icon.
mascot: Overrides the illustration in the advanced web interface.
media_cache_retention_period: Downloaded media files will be deleted after the specified number of days when set to a positive value, and re-downloaded on demand.
peers_api_enabled: A list of domain names this server has encountered in the fediverse. No data is included here about whether you federate with a given server, just that your server knows about it. This is used by services that collect statistics on federation in a general sense.
Expand Down
2 changes: 2 additions & 0 deletions config/locales/simple_form.en.yml
Expand Up @@ -77,11 +77,13 @@ en:
warn: Hide the filtered content behind a warning mentioning the filter's title
form_admin_settings:
activity_api_enabled: Counts of locally published posts, active users, and new registrations in weekly buckets
app_icon: Overrides the default app icon on mobile devices with a custom icon.
backups_retention_period: Keep generated user archives for the specified number of days.
bootstrap_timeline_accounts: These accounts will be pinned to the top of new users' follow recommendations.
closed_registrations_message: Displayed when sign-ups are closed
content_cache_retention_period: All posts and boosts from other servers will be deleted after the specified number of days. Some posts may not be recoverable. All related bookmarks, favourites and boosts will also be lost and impossible to undo.
custom_css: You can apply custom styles on the web version of Mastodon.
favicon: Overrides the default Mastodon favicon with a custom icon.
mascot: Overrides the illustration in the advanced web interface.
media_cache_retention_period: Downloaded media files will be deleted after the specified number of days when set to a positive value, and re-downloaded on demand.
peers_api_enabled: A list of domain names this server has encountered in the fediverse. No data is included here about whether you federate with a given server, just that your server knows about it. This is used by services that collect statistics on federation in a general sense.
Expand Down
24 changes: 5 additions & 19 deletions lib/tasks/branding.rake
Expand Up @@ -41,30 +41,16 @@ namespace :branding do
app_icon_source = Rails.root.join('app', 'javascript', 'images', 'app-icon.svg')
output_dest = Rails.root.join('app', 'javascript', 'icons')

rsvg_convert = Terrapin::CommandLine.new('rsvg-convert', '-w :size -h :size --keep-aspect-ratio :input -o :output')
convert = Terrapin::CommandLine.new('convert', ':input :output', environment: { 'MAGICK_CONFIGURE_PATH' => nil })

favicon_sizes = [16, 32, 48]
apple_icon_sizes = [57, 60, 72, 76, 114, 120, 144, 152, 167, 180, 1024]
android_icon_sizes = [36, 48, 72, 96, 144, 192, 256, 384, 512]

favicons = []

favicon_sizes.each do |size|
output_path = output_dest.join("favicon-#{size}x#{size}.png")
favicons << output_path
rsvg_convert.run(size: size, input: favicon_source, output: output_path)
end

convert.run(input: favicons, output: Rails.public_path.join('favicon.ico'))
# Generate favicons
IconGenerator.generate_favicons(favicon_source, output_dest, favicon_sizes)

apple_icon_sizes.each do |size|
rsvg_convert.run(size: size, input: app_icon_source, output: output_dest.join("apple-touch-icon-#{size}x#{size}.png"))
end

android_icon_sizes.each do |size|
rsvg_convert.run(size: size, input: app_icon_source, output: output_dest.join("android-chrome-#{size}x#{size}.png"))
end
# Generate app icons
IconGenerator.generate_app_icons(app_icon_source, output_dest, apple_icon_sizes, 'apple-touch-icon')
IconGenerator.generate_app_icons(app_icon_source, output_dest, android_icon_sizes, 'android-chrome')
end

desc 'Generate badge icon from SVG source files'
Expand Down