Skip to content

Commit

Permalink
Merge pull request #1152 from blockscout/tom2drum/issue-972
Browse files Browse the repository at this point in the history
Add support for custom favicon
  • Loading branch information
tom2drum authored Sep 8, 2023
2 parents 1865d9c + 93b99c5 commit be950a9
Show file tree
Hide file tree
Showing 29 changed files with 256 additions and 10 deletions.
13 changes: 11 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ RUN yarn build
# *****************************
# Production image, copy all the files and run next
FROM node:18-alpine AS runner
RUN apk add --no-cache --upgrade bash
RUN apk add --no-cache --upgrade bash curl jq unzip

### APP
WORKDIR /app
Expand All @@ -98,9 +98,18 @@ COPY --from=builder /app/package.json ./package.json
COPY --from=builder /envs-validator/index.js ./envs-validator.js
COPY --from=builder /app/deploy/tools/feature-reporter/index.js ./feature-reporter.js

# Copy scripts and ENVs file
# Copy scripts
## Entripoint
COPY --chmod=+x ./deploy/scripts/entrypoint.sh .
## ENV replacer
COPY --chmod=+x ./deploy/scripts/replace_envs.sh .
## Favicon generator
COPY --chmod=+x ./deploy/scripts/favicon_generator.sh .
COPY ./deploy/tools/favicon-generator ./deploy/tools/favicon-generator
RUN ["chmod", "-R", "777", "./deploy/tools/favicon-generator"]
RUN ["chmod", "-R", "777", "./public"]

# Copy ENVs files
COPY --from=builder /app/.env.production .
COPY --from=builder /app/.env .

Expand Down
8 changes: 8 additions & 0 deletions deploy/scripts/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ if [ $? != 0 ]; then
echo 🛑 ENV integrity check failed. 1>&2 && exit 1
fi

# Generate favicons bundle
./favicon_generator.sh
if [ $? -ne 0 ]; then
echo "👎 Unable to generate favicons bundle."
else
echo "👍 Favicons bundle successfully generated."
fi

# Execute script for replace build-time ENVs placeholders with their values at runtime
./replace_envs.sh

Expand Down
21 changes: 21 additions & 0 deletions deploy/scripts/favicon_generator.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

master_url="${NEXT_PUBLIC_FAVICON_MASTER_URL:-$NEXT_PUBLIC_NETWORK_ICON}"
export MASTER_URL="$master_url"

cd ./deploy/tools/favicon-generator
./script.sh
if [ $? -ne 0 ]; then
cd ../../../
exit 1
else
cd ../../../
favicon_folder="./public/favicon/"

echo "⏳ Replacing default favicons with freshly generated pack..."
if [ -d "$favicon_folder" ]; then
rm -r "$favicon_folder"
fi
mkdir -p "$favicon_folder"
cp -r ./deploy/tools/favicon-generator/output/* "$favicon_folder"
fi
4 changes: 4 additions & 0 deletions deploy/tools/favicon-generator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/output
config.json
response.json
favicon_package**
41 changes: 41 additions & 0 deletions deploy/tools/favicon-generator/config.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"favicon_generation": {
"api_key": "<api_key>",
"master_picture": {
"type": "url",
"url": "<master_url>"
},
"files_location": {
"type": "path",
"path": "/favicons"
},
"favicon_design": {
"desktop_browser": {},
"ios": {
"picture_aspect": "no_change",
"assets": {
"ios6_and_prior_icons": false,
"ios7_and_later_icons": true,
"precomposed_icons": false,
"declare_only_default_icon": true
}
},
"safari_pinned_tab": {
"picture_aspect": "black_and_white",
"threshold": 60
}
},
"settings": {
"compression": "3",
"scaling_algorithm": "Mitchell",
"error_on_image_too_small": true,
"readme_file": false,
"html_code_file": false,
"use_path_as_is": false
},
"versioning": {
"param_name": "ver",
"param_value": "15Zd8"
}
}
}
110 changes: 110 additions & 0 deletions deploy/tools/favicon-generator/script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/bin/bash

echo "🌀 Generating favicons bundle..."

# Check if MASTER_URL is provided
if [ -z "$MASTER_URL" ]; then
echo "🛑 Error: MASTER_URL variable is not provided."
exit 1
fi

# Check if NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY is provided
if [ -z "$NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY" ]; then
echo "🛑 Error: NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY variable is not provided."
exit 1
fi

# Mask the NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY to display only the first 8 characters
API_KEY_MASKED="${NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY:0:8}***"
echo "🆗 The following variables are provided:"
echo " MASTER_URL: $MASTER_URL"
echo " NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY: $API_KEY_MASKED"
echo

# RealFaviconGenerator API endpoint URL
API_URL="https://realfavicongenerator.net/api/favicon"

# Target folder for the downloaded assets
TARGET_FOLDER="./output"

# Path to the config JSON template file
CONFIG_TEMPLATE_FILE="config.template.json"

# Path to the generated config JSON file
CONFIG_FILE="config.json"

# Replace <api_key> and <master_url> placeholders in the JSON template file
API_KEY_VALUE="$NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY"
sed -e "s|<api_key>|$API_KEY_VALUE|" -e "s|<master_url>|$MASTER_URL|" "$CONFIG_TEMPLATE_FILE" > "$CONFIG_FILE"

# Make the API POST request with JSON data from the config file
echo "⏳ Making request to API..."
API_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" -d @"$CONFIG_FILE" "$API_URL")

# Create the response.json file with the API response
echo "$API_RESPONSE" > response.json

# Check if the API response is valid JSON and contains success status
if ! jq -e '.favicon_generation_result.result.status == "success"' <<< "$API_RESPONSE" >/dev/null; then
echo "🛑 Error: API response does not contain the expected structure or has an error status."
ERROR_MESSAGE=$(echo "$API_RESPONSE" | jq -r '.favicon_generation_result.result.error_message' | tr -d '\\')
if [ -n "$ERROR_MESSAGE" ]; then
echo "🛑 $ERROR_MESSAGE"
fi
exit 1
fi
echo "🆗 API responded with success status."

# Parse the JSON response to extract the file URL and remove backslashes
FILE_URL=$(echo "$API_RESPONSE" | jq -r '.favicon_generation_result.favicon.package_url' | tr -d '\\')
PREVIEW_URL=$(echo "$API_RESPONSE" | jq -r '.favicon_generation_result.preview_picture_url' | tr -d '\\')

# Check if FILE_URL is empty
if [ -z "$FILE_URL" ]; then
echo "🛑 File URL not found in JSON response."
exit 1
fi

echo "🆗 Found following file URL in the response: $FILE_URL"
echo "🆗 Favicon preview URL: $PREVIEW_URL"
echo

# Generate a filename based on the URL
FILE_NAME=$(basename "$FILE_URL")

# Check if the target folder exists and clear its contents if it does
if [ -d "$TARGET_FOLDER" ]; then
rm -r "$TARGET_FOLDER"
fi
mkdir -p "$TARGET_FOLDER"

# Download the file
echo "⏳ Trying to download the file..."
curl -s -L "$FILE_URL" -o "$FILE_NAME"

# Check if the download was successful
if [ $? -eq 0 ]; then
echo "🆗 File downloaded successfully."
echo
else
echo "🛑 Error: Failed to download the file."
exit 1
fi

# Unzip the downloaded file to the target folder
echo "⏳ Unzipping the file..."
unzip -q "$FILE_NAME" -d "$TARGET_FOLDER"

# Check if the unzip operation was successful
if [ $? -eq 0 ]; then
echo "🆗 File unzipped successfully."
echo
else
echo "🛑 Failed to unzip the file."
exit 1
fi

# Clean up - remove the JSON response file and temporary JSON config file
rm response.json "$CONFIG_FILE"

echo "✅ Done."
1 change: 1 addition & 0 deletions deploy/values/l2-optimism-goerli/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,4 @@ frontend:
envFromSecret:
NEXT_PUBLIC_AUTH0_CLIENT_ID: ref+vault://deployment-values/blockscout/dev/l2-optimism-goerli?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_AUTH0_CLIENT_ID
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ref+vault://deployment-values/blockscout/dev/l2-optimism-goerli?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY
1 change: 1 addition & 0 deletions deploy/values/main/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,4 @@ frontend:
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID: ref+vault://deployment-values/blockscout/dev/front-main?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY: ref+vault://deployment-values/blockscout/dev/front-main?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ref+vault://deployment-values/blockscout/dev/front-main?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY
3 changes: 3 additions & 0 deletions deploy/values/review-l2/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ frontend:
- "/account"
- "/apps"
- "/static"
- "/favicon"
- "/auth/profile"
- "/auth/unverified-email"
- "/txs"
Expand Down Expand Up @@ -143,3 +144,5 @@ frontend:
_default: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID:
_default: ref+vault://deployment-values/blockscout/dev/review-l2?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY:
_default: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY
7 changes: 7 additions & 0 deletions deploy/values/review/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ frontend:
- "/account"
- "/apps"
- "/static"
- "/favicon"
- "/auth/profile"
- "/auth/unverified-email"
- "/txs"
Expand Down Expand Up @@ -77,6 +78,10 @@ frontend:
_default: 'true'
NEXT_PUBLIC_FEATURED_NETWORKS:
_default: https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/featured-networks/eth-goerli.json
NEXT_PUBLIC_NETWORK_LOGO:
_default: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/goerli.svg
NEXT_PUBLIC_NETWORK_ICON:
_default: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/goerli.svg
NEXT_PUBLIC_API_HOST:
_default: blockscout-main.k8s-dev.blockscout.com
NEXT_PUBLIC_STATS_API_HOST:
Expand Down Expand Up @@ -123,5 +128,7 @@ frontend:
_default: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID:
_default: ref+vault://deployment-values/blockscout/dev/review?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY:
_default: ref+vault://deployment-values/blockscout/common?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY
NEXT_PUBLIC_WEB3_WALLETS:
_default: "['token_pocket','coinbase','metamask']"
12 changes: 12 additions & 0 deletions docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The app instance could be customized by passing following variables to NodeJS en
- [Homepage](ENVS.md#homepage)
- [Sidebar](ENVS.md#sidebar)
- [Footer](ENVS.md#footer)
- [Favicon](ENVS.md#favicon)
- [Views](ENVS.md#views)
- [Block](ENVS.md#block-views)
- [Misc](ENVS.md#misc)
Expand Down Expand Up @@ -132,6 +133,17 @@ The app version shown in the footer is derived from build-time ENV variables `NE

&nbsp;

### Favicon

By default, the app has generic favicon. You can override this behavior by providing the following variables. Hence, the favicon assets bundle will be generated at the container start time and will be used instead of default one.

| Variable | Type| Description | Compulsoriness | Default value | Example value |
| --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY | `string` | RealFaviconGenerator [API key](https://realfavicongenerator.net/api/) | Required | - | `<your-secret>` |
| NEXT_PUBLIC_FAVICON_MASTER_URL | `string` | - | - | `NEXT_PUBLIC_NETWORK_ICON` | `https://placekitten.com/180/180` |

&nbsp;

### Views

#### Block views
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"test:pw:docker": "docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.35.1-focal ./playwright/run-tests.sh",
"test:pw:ci": "yarn test:pw --project=$PW_PROJECT",
"test:jest": "jest",
"test:jest:watch": "jest --watch"
"test:jest:watch": "jest --watch",
"favicon:generate:dev": "./tools/scripts/favicon-generator.dev.sh"
},
"dependencies": {
"@chakra-ui/react": "2.7.1",
Expand Down
14 changes: 10 additions & 4 deletions pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class MyDocument extends Document {
return (
<Html lang="en">
<Head>
{ /* FONTS */ }
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
rel="stylesheet"
Expand All @@ -38,10 +39,15 @@ class MyDocument extends Document {
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<link rel="icon" sizes="32x32" type="image/png" href="/static/favicon-32x32.png"/>
<link rel="icon" sizes="16x16" type="image/png"href="/static/favicon-16x16.png"/>
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png"/>
<link rel="mask-icon" href="/static/safari-pinned-tab.svg" color="#5bbad5"/>

{ /* FAVICON */ }
<link rel="icon" href="/favicon/favicon.ico" sizes="48x48"/>
<link rel="icon" sizes="32x32" type="image/png" href="/favicon/favicon-32x32.png"/>
<link rel="icon" sizes="16x16" type="image/png"href="/favicon/favicon-16x16.png"/>
<link rel="apple-touch-icon" href="/favicon/apple-touch-icon-180x180.png"/>
<link rel="mask-icon" href="/favicon/safari-pinned-tab.svg"/>

{ /* OG TAGS */ }
<meta property="og:title" content="Blockscout: A block explorer designed for a decentralized world."/>
<meta
property="og:description"
Expand Down
Binary file added public/favicon/apple-touch-icon-120x120.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon/apple-touch-icon-152x152.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon/apple-touch-icon-180x180.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon/apple-touch-icon-60x60.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon/apple-touch-icon-76x76.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon/favicon.ico
Binary file not shown.
3 changes: 3 additions & 0 deletions public/favicon/safari-pinned-tab.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/static/apple-touch-icon.png
Binary file not shown.
Binary file removed public/static/favicon-16x16.png
Binary file not shown.
Binary file removed public/static/favicon-32x32.png
Binary file not shown.
3 changes: 0 additions & 3 deletions public/static/safari-pinned-tab.svg

This file was deleted.

19 changes: 19 additions & 0 deletions tools/scripts/favicon-generator.dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
secrets_file="./configs/envs/.env.secrets"
favicon_folder="./public/favicon/"
master_url="https://raw.githubusercontent.com/blockscout/frontend/main/tools/scripts/favicon.svg"

if [ ! -f "$secrets_file" ]; then
echo "Error: File '$secrets_file' not found."
exit 1
fi

dotenv \
-v MASTER_URL=$master_url \
-e $secrets_file \
-- bash -c 'cd ./deploy/tools/favicon-generator && ./script.sh'

if [ -d "$favicon_folder" ]; then
rm -r "$favicon_folder"
fi
mkdir -p "$favicon_folder"
cp -r ./deploy/tools/favicon-generator/output/* "$favicon_folder"
3 changes: 3 additions & 0 deletions tools/scripts/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit be950a9

Please sign in to comment.