All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fi.evolver.ai.vaadin.component.ChatAvatarImageItem Maven / Gradle / Ivy

The newest version!
package fi.evolver.ai.vaadin.component;

import java.io.ByteArrayInputStream;
import java.io.Serial;
import java.util.List;
import java.util.function.Consumer;

import org.vaadin.lineawesome.LineAwesomeIcon;
import org.vaadin.olli.FileDownloadWrapper;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Unit;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.contextmenu.MenuItem;
import com.vaadin.flow.component.contextmenu.SubMenu;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.menubar.MenuBar;
import com.vaadin.flow.component.menubar.MenuBarVariant;
import com.vaadin.flow.server.StreamResource;
import com.vaadin.flow.theme.lumo.LumoUtility;

import fi.evolver.ai.spring.file.AiFile;
import fi.evolver.utils.string.StringUtils;

public class ChatAvatarImageItem extends ChatAvatarItem {

	@Serial
	private static final long serialVersionUID = 1L;

	public ChatAvatarImageItem(String user, String message, List resultImages, Consumer subMenuBuilder) {
		super(user, createContent(message, resultImages, subMenuBuilder));
	}

	public ChatAvatarImageItem(String user, List resultImages, Consumer subMenuBuilder) {
		this(user, null, resultImages, subMenuBuilder);
	}

	public ChatAvatarImageItem(String user, String message, List resultImages) {
		this(user, message, resultImages, null);
	}

	public ChatAvatarImageItem(String user, List resultImages) {
		this(user, null, resultImages);
	}

	private static Component createContent(String message, List resultImages,
			Consumer subMenuBuilder) {
		Div content = new Div();
		if (StringUtils.hasText(message))
			content.add(new Paragraph(message));
		content.add(createImageContent(resultImages, subMenuBuilder));
		return content;
	}

	private static Component createImageContent(List resultImages, Consumer subMenuBuilder) {
		FormLayout imageContent = new FormLayout();
		imageContent.setWidthFull();
		imageContent.setResponsiveSteps(
				new FormLayout.ResponsiveStep("0", 1),
				new FormLayout.ResponsiveStep("600px", 2),
				new FormLayout.ResponsiveStep("900px", 3),
				new FormLayout.ResponsiveStep("1200px", 4));
		for (AiFile img : resultImages) {
			Div item = createImageComponent(img, subMenuBuilder);
			item.getElement().getStyle().setMarginTop("1em");
			item.addClassName(LumoUtility.Display.INLINE);
			Div container = new Div(item);
			container.addClassName(LumoUtility.Display.FLEX);
			imageContent.add(container);
		}
		return imageContent;
	}

	private static Div createImageComponent(AiFile image, Consumer subMenuBuilder) {
		StreamResource resource = new StreamResource(image.fileName(), () -> new ByteArrayInputStream(image.data()));
		Image imageItem = new Image(resource, image.fileName());
		imageItem.setMaxWidth(100, Unit.PERCENTAGE);
		imageItem.setMaxHeight(50, Unit.VH);

		Component imageMenu = createImageMenu(image, subMenuBuilder);
		Component downloadButton = createImageDownloadButton(resource);
		Div imageContainer = new Div(imageMenu, downloadButton, imageItem);
		imageContainer.addClassNames(LumoUtility.Position.RELATIVE);
		return imageContainer;
	}

	private static MenuBar createImageMenu(AiFile image, Consumer subMenuBuilder) {
		MenuBar menuBar = new MenuBar();
		menuBar.addThemeVariants(MenuBarVariant.LUMO_ICON, MenuBarVariant.LUMO_PRIMARY);
		menuBar.addClassNames(LumoUtility.Position.ABSOLUTE);
		menuBar.setHeight(2.5f, Unit.EM);
		menuBar.getElement().getStyle().set("left", "0");

		MenuItem showBtn = menuBar.addItem(LineAwesomeIcon.SEARCH_PLUS_SOLID.create(), menuBar.getTranslation("componen.chatImageItem.show"));
		showBtn.addClickListener(e -> {
			Dialog dialog = createDialog(image);
			dialog.open();
		});

		if (subMenuBuilder != null) {
			SubMenu subItems = menuBar.addItem(LineAwesomeIcon.ELLIPSIS_H_SOLID.create()).getSubMenu();
			subMenuBuilder.accept(subItems);
		}

		return menuBar;
	}

	private static Component createImageDownloadButton(StreamResource resource) {
		FileDownloadWrapper download = new FileDownloadWrapper(resource);
		Button downloadButton = new Button(LineAwesomeIcon.DOWNLOAD_SOLID.create());
		downloadButton.addThemeVariants(ButtonVariant.LUMO_ICON, ButtonVariant.LUMO_PRIMARY);
		downloadButton.setTooltipText(downloadButton.getTranslation("componen.chatImageItem.download"));
		downloadButton.getElement().getStyle().set("margin", "calc(var(--lumo-space-xs) / 2)");
		download.wrapComponent(downloadButton);
		download.addClassName(LumoUtility.Position.ABSOLUTE);
		download.setHeight(2.5f, Unit.EM);
		download.getElement().getStyle().set("right", "0");

		return download;
	}

	private static Dialog createDialog(AiFile image) {
		StreamResource resource = new StreamResource(image.fileName(), () -> new ByteArrayInputStream(image.data()));
		Dialog dialog = new Dialog();
		dialog.setHeightFull();

		Button closeBtn = new Button(LineAwesomeIcon.TIMES_SOLID.create());
		closeBtn.addThemeVariants(ButtonVariant.LUMO_ICON, ButtonVariant.LUMO_TERTIARY);
		closeBtn.addClickListener(e -> dialog.close());
		closeBtn.addClassName(LumoUtility.Position.ABSOLUTE);
		closeBtn.getElement().getStyle().set("right", "var(--lumo-space-l)");
		dialog.add(closeBtn);

		Div content = new Div();
		content.addClassNames(LumoUtility.Display.FLEX, LumoUtility.AlignItems.CENTER,
				LumoUtility.JustifyContent.CENTER);
		content.setSizeFull();

		Image dialogImage = new Image(resource, image.fileName());
		dialogImage.setMaxWidth(100, Unit.PERCENTAGE);
		dialogImage.setMaxHeight(100, Unit.PERCENTAGE);

		content.add(dialogImage);
		dialog.add(content);
		return dialog;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy