K0IN / Notify

A small deno deploy / self hosted solution to send web push notifications with webhooks
https://notify-demo.deno.dev/
MIT License
141 stars 22 forks source link

UI Improvement , Pagination and Manifest assets #177

Open mskian opened 1 month ago

mskian commented 1 month ago

Front-end UI Need Some Improvements

.push-message {
    white-space: pre-line;
}
/assets/icons/desktop-screenshot.png
{
  "name": "notify app",
  "short_name": "notify",
  "start_url": "/",
  "display": "standalone",
  "orientation": "portrait",
  "background_color": "#000",
  "theme_color": "#000",
  "categories": [
    "utilities",
    "productivity"
  ],
  "description": "Notify is a simple app that allows you to receive notifications from a webhook.",
  "icons": [
    {
      "src": "/assets/notify_big.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/assets/icons/notify_big.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    },
    {
      "src": "/assets/icons/notify_small.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/assets/icons/notify_small.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "maskable"
    }
  ],
  "screenshots": [
    {
      "src": "/assets/screenshots/mobile-screenshot.png",
      "sizes": "1170x2532",
      "type": "image/png",
      "form_factor": "narrow",
      "label": "App screenshot with example notification",
      "platform": "ios"
    },
    {
      "src": "/assets/screenshots/mobile-screenshot.png",
      "sizes": "1170x2532",
      "type": "image/png",
      "form_factor": "narrow",
      "label": "App screenshot with example notification",
      "platform": "android"
    },
    {
      "src": "/assets/icons/desktop-screenshot.png",
      "sizes": "2038x1301",
      "type": "image/png",
      "form_factor": "wide",
      "label": "Home screen of Awesome App",
      "platform": "windows"
    },
    {
      "src": "/assets/icons/desktop-screenshot.png",
      "sizes": "2038x1301",
      "type": "image/png",
      "form_factor": "wide",
      "label": "Home screen of Awesome App",
      "platform": "macos"
    }
  ]
}
codeautopilot[bot] commented 1 month ago

Potential solution

To address the task, we need to make three main changes:

  1. Update the CSS to allow multi-line text display.
  2. Correct the folder path for the desktop preview image in the manifest file.
  3. Implement pagination in the Messages component.

How to implement

1. Multi-line Text Display

To ensure that text within the messagebody class displays on multiple lines, we need to add the white-space: pre-line property to the CSS.

File: app/frontend/src/components/message/message.css

.message {
    max-width: 100%;
    display: grid;
    grid-template-areas:
        "title time"
        "body body"
        "tags tags"
        "image image";
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-content: space-between;
    padding: 10px;
}

.messagetitle {
    grid-area: title;
    font-size: 1.2em;
    padding-left: 5px;
    overflow: hidden;
    margin-top: 0px;
}

.messagetime {
    grid-area: time;
    justify-self: right;
    padding-right: 5px;
    margin-top: 0px;
}

.messagebody {
    grid-area: body;
    padding-left: 5px;
    padding-right: 5px;
    white-space: pre-line; /* Add this line to allow multi-line text */
}

.messagetags {
    grid-area: tags;
}

.messageimage {
    grid-area: image;
    max-width: 100%;
    max-height: 25vh;
    justify-self: center;
}

2. Correct Folder Path for Desktop Preview Image

We need to update the manifest.json file to correct the path for the desktop screenshot image.

File: app/frontend/src/manifest.json

{
  "name": "notify app",
  "short_name": "notify",
  "start_url": "/",
  "display": "standalone",
  "orientation": "portrait",
  "background_color": "#000",
  "theme_color": "#000",
  "categories": [
    "utilities",
    "productivity"
  ],
  "description": "Notify is a simple app that allows you to receive notifications from a webhook.",
  "icons": [
    {
      "src": "/assets/icons/notify_big.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/assets/icons/notify_big.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    },
    {
      "src": "/assets/icons/notify_small.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/assets/icons/notify_small.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "maskable"
    }
  ],
  "screenshots": [
    {
      "src": "/assets/screenshots/mobile-screenshot.png",
      "sizes": "1170x2532",
      "type": "image/png",
      "form_factor": "narrow",
      "label": "App screenshot with example notification",
      "platform": "ios"
    },
    {
      "src": "/assets/screenshots/mobile-screenshot.png",
      "sizes": "1170x2532",
      "type": "image/png",
      "form_factor": "narrow",
      "label": "App screenshot with example notification",
      "platform": "android"
    },
    {
      "src": "/assets/screenshots/desktop-screenshot.png",
      "sizes": "2038x1301",
      "type": "image/png",
      "form_factor": "wide",
      "label": "Home screen of Awesome App",
      "platform": "windows"
    },
    {
      "src": "/assets/screenshots/desktop-screenshot.png",
      "sizes": "2038x1301",
      "type": "image/png",
      "form_factor": "wide",
      "label": "Home screen of Awesome App",
      "platform": "macos"
    }
  ]
}

3. Implement Pagination

To implement pagination in the Messages component, we need to manage the state for the current page and the number of messages per page, and provide controls to navigate between pages.

File: app/frontend/src/components/messages/messages.tsx

import { FunctionalComponent, h } from 'preact';
import 'preact-material-components/Theme/style.css';
import { useLastOpenTime } from '../../hooks/use-lastopen';
import { useMessageReceiver } from '../../hooks/use-messagereceiver';
import Message from '../message/message';
import style from './messages.css';
import { useEffect, useState } from 'preact/hooks';

const Messages: FunctionalComponent = () => {
    const messages = useMessageReceiver();
    const lastOpenTime = useLastOpenTime();

    const newMessages = messages.filter(e => !(e.receivedAt <= lastOpenTime));
    const oldMessages = messages.filter(e => e.receivedAt <= lastOpenTime);

    const [currentPage, setCurrentPage] = useState(1);
    const messagesPerPage = 10;

    const totalMessages = newMessages.length + oldMessages.length;
    const totalPages = Math.ceil(totalMessages / messagesPerPage);

    const paginateMessages = (messages, page) => {
        const startIndex = (page - 1) * messagesPerPage;
        return messages.slice(startIndex, startIndex + messagesPerPage);
    };

    const handleNextPage = () => {
        if (currentPage < totalPages) {
            setCurrentPage(currentPage + 1);
        }
    };

    const handlePreviousPage = () => {
        if (currentPage > 1) {
            setCurrentPage(currentPage - 1);
        }
    };

    useEffect(() => {
        if (navigator && (navigator as any).clearAppBadge) {
            (navigator as any).clearAppBadge();
        }
    }, [messages]);

    const paginatedNewMessages = paginateMessages(newMessages, currentPage);
    const paginatedOldMessages = paginateMessages(oldMessages, currentPage - Math.ceil(newMessages.length / messagesPerPage));

    return (
        <div class={style.content}>
            <div class={style.main}>
                <ul class={style.messagelist}>
                    {paginatedNewMessages.map((message) => (
                        <li class={style.nobullet}>
                            <Message message={message} />
                        </li>)
                    )}
                </ul>

                {(newMessages.length > 0) && <div class={style.divider}></div>}

                <ul class={style.messagelist}>
                    {paginatedOldMessages.map((message) => (
                        <li class={style.nobullet}>
                            <Message message={message} />
                        </li>)
                    )}
                </ul>

                <div class={style.pagination}>
                    <button onClick={handlePreviousPage} disabled={currentPage === 1}>Previous</button>
                    <span>Page {currentPage} of {totalPages}</span>
                    <button onClick={handleNextPage} disabled={currentPage === totalPages}>Next</button>
                </div>
            </div>
        </div>
    );
};

export default Messages;

This implementation ensures that:

  1. Text within the messagebody class displays on multiple lines.
  2. The desktop preview image path in the manifest file is corrected.
  3. Messages are displayed in a paginated manner, improving the user experience when dealing with a large number of messages.

Click here to create a Pull Request with the proposed solution

Files used for this task:

Changes on app/frontend/src/components/message/message.css To address the issue of displaying multi-line text in the message component, you need to add a CSS rule that allows text to wrap and display on multiple lines. This can be achieved by using the `white-space` property with the value `pre-line`. Here's the updated CSS for the `messagebody` class in the `app/frontend/src/components/message/message.css` file: ```css .message { max-width: 100%; display: grid; grid-template-areas: "title time" "body body" "tags tags" "image image"; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: space-between; padding: 10px; } .messagetitle { grid-area: title; font-size: 1.2em; padding-left: 5px; overflow: hidden; margin-top: 0px; } .messagetime { grid-area: time; justify-self: right; padding-right: 5px; margin-top: 0px; } .messagebody { grid-area: body; padding-left: 5px; padding-right: 5px; white-space: pre-line; /* Add this line to allow multi-line text */ } .messagetags { grid-area: tags; } .messageimage { grid-area: image; max-width: 100%; max-height: 25vh; justify-self: center; } ``` This change will ensure that any text within the `messagebody` class will display on multiple lines if necessary, improving the readability of messages that contain longer text. If there are no other changes required for this file, this should be the only modification needed.
Changes on app/frontend/src/manifest.json To address the issue in the `app/frontend/src/manifest.json` file, we need to correct the folder path for the desktop preview image. The current path is incorrect, and it should be updated to point to the correct location. ### Steps to Correct the Folder Path 1. **Identify the Correct Path**: Ensure that the correct path to the desktop screenshot image is known. According to the issue description, the correct path should be `/assets/screenshots/desktop-screenshot.png`. 2. **Update the Manifest File**: Modify the `src` attribute of the desktop screenshot entries in the `screenshots` array to reflect the correct path. ### Updated `manifest.json` File Here is the corrected version of the `manifest.json` file: ```json { "name": "notify app", "short_name": "notify", "start_url": "/", "display": "standalone", "orientation": "portrait", "background_color": "#000", "theme_color": "#000", "categories": [ "utilities", "productivity" ], "description": "Notify is a simple app that allows you to receive notifications from a webhook.", "icons": [ { "src": "/assets/icons/notify_big.png", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { "src": "/assets/icons/notify_big.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }, { "src": "/assets/icons/notify_small.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { "src": "/assets/icons/notify_small.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" } ], "screenshots": [ { "src": "/assets/screenshots/mobile-screenshot.png", "sizes": "1170x2532", "type": "image/png", "form_factor": "narrow", "label": "App screenshot with example notification", "platform": "ios" }, { "src": "/assets/screenshots/mobile-screenshot.png", "sizes": "1170x2532", "type": "image/png", "form_factor": "narrow", "label": "App screenshot with example notification", "platform": "android" }, { "src": "/assets/screenshots/desktop-screenshot.png", "sizes": "2038x1301", "type": "image/png", "form_factor": "wide", "label": "Home screen of Awesome App", "platform": "windows" }, { "src": "/assets/screenshots/desktop-screenshot.png", "sizes": "2038x1301", "type": "image/png", "form_factor": "wide", "label": "Home screen of Awesome App", "platform": "macos" } ] } ``` ### Summary - **Corrected the folder path** for the desktop screenshot image in the `manifest.json` file. - **Ensured consistency** by updating both entries for the desktop screenshot. This change will ensure that the desktop preview image is correctly referenced and displayed in the application.
Changes on app/frontend/src/components/messages/messages.tsx To implement pagination logic in the `Messages` component, we need to break down the list of messages into pages and provide a way for users to navigate between these pages. Here's a step-by-step plan to achieve this: 1. **State Management for Pagination**: - Introduce state variables to manage the current page and the number of messages per page. 2. **Pagination Logic**: - Calculate the messages to be displayed based on the current page and the number of messages per page. 3. **Pagination Controls**: - Add buttons or controls to navigate between pages. 4. **Update the Render Method**: - Modify the render method to display only the messages for the current page and include the pagination controls. Here's the updated code for `app/frontend/src/components/messages/messages.tsx`: ```typescript import { FunctionalComponent, h } from 'preact'; import 'preact-material-components/Theme/style.css'; import { useLastOpenTime } from '../../hooks/use-lastopen'; import { useMessageReceiver } from '../../hooks/use-messagereceiver'; import Message from '../message/message'; import style from './messages.css'; import { useEffect, useState } from 'preact/hooks'; const Messages: FunctionalComponent = () => { const messages = useMessageReceiver(); const lastOpenTime = useLastOpenTime(); const newMessages = messages.filter(e => !(e.receivedAt <= lastOpenTime)); const oldMessages = messages.filter(e => e.receivedAt <= lastOpenTime); const [currentPage, setCurrentPage] = useState(1); const messagesPerPage = 10; const totalMessages = newMessages.length + oldMessages.length; const totalPages = Math.ceil(totalMessages / messagesPerPage); const paginateMessages = (messages, page) => { const startIndex = (page - 1) * messagesPerPage; return messages.slice(startIndex, startIndex + messagesPerPage); }; const handleNextPage = () => { if (currentPage < totalPages) { setCurrentPage(currentPage + 1); } }; const handlePreviousPage = () => { if (currentPage > 1) { setCurrentPage(currentPage - 1); } }; useEffect(() => { if (navigator && (navigator as any).clearAppBadge) { (navigator as any).clearAppBadge(); } }, [messages]); const paginatedNewMessages = paginateMessages(newMessages, currentPage); const paginatedOldMessages = paginateMessages(oldMessages, currentPage - Math.ceil(newMessages.length / messagesPerPage)); return (
    {paginatedNewMessages.map((message) => (
  • ) )}
{(newMessages.length > 0) &&
}
    {paginatedOldMessages.map((message) => (
  • ) )}
Page {currentPage} of {totalPages}
); }; export default Messages; ``` ### Explanation: 1. **State Variables**: - `currentPage` to keep track of the current page. - `messagesPerPage` to define how many messages are displayed per page. 2. **Pagination Logic**: - `paginateMessages` function slices the messages array to get the messages for the current page. - `handleNextPage` and `handlePreviousPage` functions update the `currentPage` state. 3. **Render Method**: - `paginatedNewMessages` and `paginatedOldMessages` are calculated based on the current page. - Pagination controls (Previous and Next buttons) are added to navigate between pages. This implementation ensures that the messages are displayed in a paginated manner, improving the user experience when dealing with a large number of messages.
mskian commented 1 month ago

Oh My AI Boy Good work and Suggestion 😀