Skip to content

Commit

Permalink
feat: add the notification mechanism implementation
Browse files Browse the repository at this point in the history
Signed-off-by: guqing <i@guqing.email>
  • Loading branch information
guqing committed Sep 8, 2023
1 parent 31675db commit a572c51
Show file tree
Hide file tree
Showing 90 changed files with 6,063 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@
* @author guqing
* @since 2.0.0
*/
public interface CommentSubject<T extends Extension> extends ExtensionPoint {
public interface CommentSubject<T extends Extension> extends ExtensionPoint {

Mono<T> get(String name);

default Mono<SubjectDisplay> getSubjectDisplay(String name) {
return Mono.empty();
}

boolean supports(Ref ref);

record SubjectDisplay(String title, String url, String kindName) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package run.halo.app.core.extension.notification;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

import io.swagger.v3.oas.annotations.media.Schema;
import java.time.Instant;
import lombok.Data;
import lombok.EqualsAndHashCode;
import run.halo.app.extension.AbstractExtension;
import run.halo.app.extension.GVK;

/**
* <p>{@link Notification} is a custom extension that used to store notification information for
* inner use, it's on-site notification.</p>
*
* <p>Supports the following operations:</p>
* <ul>
* <li>Marked as read: {@link NotificationSpec#setUnread(boolean)}</li>
* <li>Get the last read time: {@link NotificationSpec#getLastReadAt()}</li>
* <li>Filter by recipient: {@link NotificationSpec#getRecipient()}</li>
* </ul>
*
* @author guqing
* @see Reason
* @see ReasonType
* @since 2.9.0
*/
@Data
@EqualsAndHashCode(callSuper = true)
@GVK(group = "notification.halo.run", version = "v1alpha1", kind = "Notification", plural =
"notifications", singular = "notification")
public class Notification extends AbstractExtension {

@Schema
private NotificationSpec spec;

@Data
public static class NotificationSpec {
@Schema(requiredMode = REQUIRED, minLength = 1, description = "The name of user")
private String recipient;

@Schema(requiredMode = REQUIRED, minLength = 1, description = "The name of reason")
private String reason;

@Schema(requiredMode = REQUIRED, minLength = 1)
private String title;

@Schema(requiredMode = REQUIRED)
private String rawContent;

@Schema(requiredMode = REQUIRED)
private String htmlContent;

private boolean unread;

private Instant lastReadAt;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package run.halo.app.core.extension.notification;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import run.halo.app.extension.AbstractExtension;
import run.halo.app.extension.GVK;

/**
* <p>{@link NotificationTemplate} is a custom extension that defines a notification template.</p>
* <p>It describes the notification template's name, description, and the template content.</p>
* <p>{@link Spec#getReasonSelector()} is used to select the template by reasonType and language,
* if multiple templates are matched, the best match will be selected. This is useful when you
* want to override the default template.</p>
*
* @author guqing
* @since 2.9.0
*/
@Data
@EqualsAndHashCode(callSuper = true)
@GVK(group = "notification.halo.run", version = "v1alpha1", kind = "NotificationTemplate",
plural = "notificationtemplates", singular = "notificationtemplate")
public class NotificationTemplate extends AbstractExtension {

@Schema
private Spec spec;

@Data
@Schema(name = "NotificationTemplateSpec")
public static class Spec {
@Schema
private ReasonSelector reasonSelector;

@Schema
private Template template;
}

@Data
@Schema(name = "TemplateContent")
public static class Template {
@Schema(requiredMode = REQUIRED, minLength = 1)
private String title;

private String htmlBody;

private String rawBody;
}

@Data
public static class ReasonSelector {
@Schema(requiredMode = REQUIRED, minLength = 1)
private String reasonType;

@Schema(requiredMode = REQUIRED, minLength = 1, defaultValue = "default")
private String language;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package run.halo.app.core.extension.notification;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import run.halo.app.extension.AbstractExtension;
import run.halo.app.extension.GVK;

/**
* <p>{@link NotifierDescriptor} is a custom extension that defines a notifier.</p>
* <p>It describes the notifier's name, description, and the extension name of the notifier to
* let the user know what the notifier is and what it can do in the UI and also let the
* {@code NotificationCenter} know how to load the notifier and prepare the notifier's settings.</p>
*
* @author guqing
* @since 2.9.0
*/
@Data
@EqualsAndHashCode(callSuper = true)
@GVK(group = "notification.halo.run", version = "v1alpha1", kind = "NotifierDescriptor",
plural = "notifierDescriptors", singular = "notifierDescriptor")
public class NotifierDescriptor extends AbstractExtension {

@Schema
private Spec spec;

@Data
@Schema(name = "NotifierDescriptorSpec")
public static class Spec {
@Schema(requiredMode = REQUIRED, minLength = 1)
private String displayName;

private String description;

@Schema(requiredMode = REQUIRED, minLength = 1)
private String notifierExtName;

private SettingRef senderSettingRef;

private SettingRef receiverSettingRef;
}

@Data
@Schema(name = "NotifierSettingRef")
public static class SettingRef {
@Schema(requiredMode = REQUIRED)
private String name;

@Schema(requiredMode = REQUIRED)
private String group;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package run.halo.app.core.extension.notification;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import run.halo.app.extension.AbstractExtension;
import run.halo.app.extension.GVK;
import run.halo.app.notification.ReasonAttributes;

/**
* <p>{@link Reason} is a custom extension that defines a reason for a notification, It represents
* an instance of a {@link ReasonType}.</p>
* <p>It can be understood as an event that triggers a notification.</p>
*
* @author guqing
* @since 2.9.0
*/
@Data
@EqualsAndHashCode(callSuper = true)
@GVK(group = "notification.halo.run", version = "v1alpha1", kind = "Reason", plural =
"reasons", singular = "reason")
public class Reason extends AbstractExtension {

@Schema
private Spec spec;

@Data
@Schema(name = "ReasonSpec")
public static class Spec {
@Schema(requiredMode = REQUIRED)
private String reasonType;

@Schema(requiredMode = REQUIRED)
private Subject subject;

@Schema(requiredMode = REQUIRED)
private String author;

@Schema(implementation = ReasonAttributes.class, requiredMode = NOT_REQUIRED,
description = "Attributes used to transfer data")
private ReasonAttributes attributes;
}

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "ReasonSubject")
public static class Subject {
@Schema(requiredMode = REQUIRED)
private String apiVersion;

@Schema(requiredMode = REQUIRED)
private String kind;

@Schema(requiredMode = REQUIRED)
private String name;

@Schema(requiredMode = REQUIRED)
private String title;

private String url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package run.halo.app.core.extension.notification;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
import run.halo.app.extension.AbstractExtension;
import run.halo.app.extension.GVK;

/**
* <p>{@link ReasonType} is a custom extension that defines a type of reason.</p>
* <p>One {@link ReasonType} can have multiple {@link Reason}s to notify.</p>
*
* @author guqing
* @see NotificationTemplate
* @see Reason
* @since 2.9.0
*/
@Data
@EqualsAndHashCode(callSuper = true)
@GVK(group = "notification.halo.run", version = "v1alpha1", kind = "ReasonType",
plural = "reasontypes", singular = "reasontype")
public class ReasonType extends AbstractExtension {
public static final String LOCALIZED_RESOURCE_NAME_ANNO =
"notification.halo.run/localized-resource-name";

@Schema
private Spec spec;

@Data
@Schema(name = "ReasonTypeSpec")
public static class Spec {

@Schema(requiredMode = REQUIRED, minLength = 1)
private String displayName;

@Schema(requiredMode = REQUIRED, minLength = 1)
private String description;

private List<ReasonProperty> properties;
}

@Data
public static class ReasonProperty {
@Schema(requiredMode = REQUIRED, minLength = 1)
private String name;

@Schema(requiredMode = REQUIRED, minLength = 1)
private String type;

private String description;

@Schema(defaultValue = "false")
private boolean optional;
}
}
Loading

0 comments on commit a572c51

Please sign in to comment.