This commit is contained in:
2026-04-29 14:58:02 +08:00
parent e729f9bd31
commit b98c66ca21
370 changed files with 55094 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
+7
View File
@@ -0,0 +1,7 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<ScalaCodeStyleSettings>
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
</ScalaCodeStyleSettings>
</code_scheme>
</component>
+5
View File
@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="demo3063-session_jwt" />
<module name="cyynote" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="cyynote" options="-parameters" />
<module name="demo3063-session_jwt" options="-parameters" />
</option>
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EditMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
+35
View File
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="sonatype-nexus-snapshots" />
<option name="name" value="Sonatype Nexus Snapshots" />
<option name="url" value="https://oss.sonatype.org/content/repositories/snapshots" />
</remote-repository>
<remote-repository>
<option name="id" value="sonatype-nexus-snapshots" />
<option name="name" value="Sonatype Nexus Snapshots" />
<option name="url" value="http://mirrors.cloud.tencent.com/nexus/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="http://mirrors.cloud.tencent.com/nexus/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK" />
</project>
+124
View File
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
+107
View File
@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cyynote</groupId>
<artifactId>cyynote</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>cyy note</description>
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>3.0.5</version>
<relativePath />
</parent>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-web</artifactId>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-sessionstate-jwt</artifactId>
</dependency>
<!-- wood-solon-plugin 相对于 wood;增加了 @Db 的注入支持 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>wood-solon-plugin</artifactId>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-security-auth</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.21</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.20</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.46.1.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.noear</groupId>
<artifactId>solon-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,30 @@
package com.cyynote;
import com.cyynote.dso.AuthProcessorImpl;
import com.cyynote.dso.DsHelper;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import org.noear.solon.auth.AuthProcessor;
import org.noear.solon.auth.AuthUtil;
import org.noear.wood.cache.ICacheServiceEx;
import org.noear.wood.cache.LocalCache;
@Configuration
public class Config {
public static final ICacheServiceEx cache = (new LocalCache("test", 60)).nameSet("test");
@Bean(value = "db1", typed = true)
public DataSource db1(@Inject("${test.db1}") HikariDataSource dataSource) {
DsHelper.initData((DataSource)dataSource);
return (DataSource)dataSource;
}
@Bean
public void authAdapter() {
AuthUtil.adapter()
.processor((AuthProcessor)new AuthProcessorImpl());
}
}
@@ -0,0 +1,12 @@
package com.cyynote;
import org.noear.solon.Solon;
import org.noear.wood.WoodConfig;
public class WebApp {
public static void main(String[] args) {
Solon.start(com.cyynote.WebApp.class, args);
WoodConfig.onExecuteAft(cmd -> System.out.println("[Wood]" + cmd.text + "\r\n" + cmd.paramMap()));
}
}
@@ -0,0 +1,103 @@
package com.cyynote.controller;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.cyynote.controller.BaseController;
import com.cyynote.model.NoteModel;
import com.cyynote.model.UserModel;
import com.cyynote.payload.request.LoginRequest;
import com.cyynote.payload.request.SignupRequest;
import java.sql.SQLException;
import java.util.List;
import java.util.logging.Logger;
import com.cyynote.payload.request.UpdatePasswordRequest;
import org.noear.solon.annotation.Body;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Post;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Result;
import org.noear.wood.DbContext;
import org.noear.wood.DbTableQuery;
import org.noear.wood.annotation.Db;
@Mapping("/api/auth")
@Controller
public class AuthController extends BaseController {
private static final Logger log = Logger.getLogger(com.cyynote.controller.AuthController.class.getName());
@Db
DbContext db;
@Mapping("/logout")
public void logout(Context ctx) {
ctx.sessionClear();
}
@Post
@Mapping("/signin")
public Result signin(Context ctx, @Body LoginRequest loginRequest) throws SQLException {
log.info("name:" + loginRequest.getUsername());
log.info("password:" + loginRequest.getPassword());
long count = db.table("user").selectCount();
log.info("countUser:" + count);
List<UserModel> all = ((DbTableQuery)this.db.table("user")).selectList("*", UserModel.class);
log.info( all.toString());
UserModel model = (UserModel)((DbTableQuery)((DbTableQuery)this.db.table("user").whereEq("username", loginRequest.getUsername())).andEq("password", loginRequest.getPassword())).selectItem("*", UserModel.class);
if ("admin".equals(model.getUsername())) {
ctx.sessionSet("user_name", loginRequest.getUsername());
ctx.sessionSet("user_id", model.getId());
JSONObject obj = new JSONObject();
String token = ctx.sessionState().sessionToken();
obj.put("accessToken", token);
obj.put("id", Integer.valueOf(1));
obj.put("username", loginRequest.getUsername());
obj.put("email", "1");
obj.put("roles", "1");
int flag = ((DbTableQuery)this.db.table("user").set("token", token).set("logintime", DateUtil.now()).whereEq("id", model.getId())).update();
System.out.println(flag);
return Result.succeed(obj);
}
return Result.failure();
}
@Post
@Mapping("/updatePassword")
public Result updatePassword(Context ctx, @Body UpdatePasswordRequest loginRequest) throws SQLException {
log.info("name:" + loginRequest.getUsername());
log.info("old - password:" + loginRequest.getOldpassword());
log.info("new - password:" + loginRequest.getNewpassword());
long count = db.table("user").selectCount();
log.info("countUser:" + count);
List<UserModel> all = ((DbTableQuery)this.db.table("user")).selectList("*", UserModel.class);
log.info( all.toString());
UserModel model = (UserModel)((DbTableQuery)((DbTableQuery)this.db.table("user").whereEq("username", loginRequest.getUsername())).andEq("password", loginRequest.getOldpassword())).selectItem("*", UserModel.class);
if ("admin".equals(model.getUsername())) {
int flag = ((DbTableQuery)this.db.table("user").set("password", loginRequest.getNewpassword()).whereEq("id", model.getId())).update();
System.out.println(flag);
return Result.succeed(flag);
}
return Result.failure();
}
@Post
@Mapping("/signup")
public Result signup(@Body SignupRequest signUpRequest) {
log.info("signUpRequest:" + JSONObject.toJSONString(signUpRequest, new com.alibaba.fastjson2.JSONWriter.Feature[0]));
JSONObject obj = new JSONObject();
return Result.succeed(obj);
}
}
@@ -0,0 +1,6 @@
package com.cyynote.controller;
import org.noear.solon.web.cors.annotation.CrossOrigin;
@CrossOrigin(origins = "*")
public class BaseController {}
@@ -0,0 +1,55 @@
package com.cyynote.controller;
import com.cyynote.controller.BaseController;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Delete;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Patch;
import org.noear.solon.annotation.Post;
import org.noear.solon.annotation.Put;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.ModelAndView;
@Controller
public class DemoController extends BaseController {
@Mapping("/demo")
public Object test() {
ModelAndView model = new ModelAndView("beetl.htm");
model.put("title", "dock");
model.put("message", "world!");
return model;
}
@Post
@Mapping("post")
public String test_post(Context context) {
return context.param("name");
}
@Put
@Mapping("put")
public String test_put(Context context, String name) {
return context.param("name");
}
@Delete
@Mapping("delete")
public String test_delete(Context context, String name) {
return context.param("name");
}
@Patch
@Mapping("patch")
public String test_patch(Context context, String name) {
return context.param("name");
}
@Get
@Mapping("get")
public String test_post_get(Context context) {
return context.path();
}
}
@@ -0,0 +1,44 @@
package com.cyynote.controller;
import io.jsonwebtoken.Claims;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
import org.noear.solon.core.handle.Result;
import org.noear.solon.core.route.RouterInterceptor;
import org.noear.solon.core.route.RouterInterceptorChain;
import org.noear.solon.sessionstate.jwt.JwtUtils;
@Component
public class JwtInterceptor implements RouterInterceptor {
public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
boolean flag = true;
if ("/api/auth/signup".equals(ctx.path()) ||
"/api/auth/signin".equals(ctx.path()) ||
"/demo".equals(ctx.path()) ||
"/api/auth/logout".equals(ctx.path())
)
flag = false;
if (flag)
if (null != ctx.header("Authorization")) {
String token = ctx.header("Authorization");
token = token.replace("Bearer ", "");
System.out.println("token:" + token);
Claims claims = JwtUtils.parseJwt(token);
System.out.println("claims:" + claims);
if (null != claims) {
System.out.println("username:" + claims.get("user_name"));
System.out.println("exp:" + claims.get("exp"));
} else {
ctx.status(401);
ctx.render(Result.failure(401, ""));
}
} else {
ctx.status(401);
ctx.render(Result.failure(401, ""));
}
chain.doIntercept(ctx, mainHandler);
}
}
@@ -0,0 +1,207 @@
package com.cyynote.controller;
import cn.hutool.*;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONObject;
import com.cyynote.controller.BaseController;
import com.cyynote.dso.NoteSqlAnnotation;
import com.cyynote.model.HistoryModel;
import com.cyynote.model.NoteModel;
import com.cyynote.payload.request.NoteRequest;
import com.cyynote.util.TreeBuild;
import com.cyynote.util.TreeNode;
import io.jsonwebtoken.Claims;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;
import org.noear.solon.annotation.Body;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Path;
import org.noear.solon.annotation.Post;
import org.noear.solon.annotation.Put;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Result;
import org.noear.solon.sessionstate.jwt.JwtUtils;
import org.noear.solon.web.cors.annotation.CrossOrigin;
import org.noear.wood.DbContext;
import org.noear.wood.DbTableQuery;
import org.noear.wood.annotation.Db;
@Mapping("/api/note")
@Controller
public class NoteController extends BaseController {
private static final Logger log = Logger.getLogger(com.cyynote.controller.NoteController.class.getName());
@Db
NoteSqlAnnotation mapper;
@Db
DbContext db;
private static final String QUERY_F = "id,pid,title,createtime,updatetime,viewtime,flag";
@Get
@Mapping("get1")
public String test_post_get(Context context, @Path String appname) {
return context.path();
}
@Post
@Mapping("post")
public String test_post(Context context) {
return context.param("name");
}
@Put
@Mapping("put")
public String test_put(Context context, String name) {
return context.param("name");
}
@Get
@Mapping("/all")
public Result noteAccess(Context ctx) throws Exception {
List<NoteModel> all = ((DbTableQuery)this.db.table("note").whereEq("flag", Integer.valueOf(1))).selectList("id,pid,title,createtime,updatetime,viewtime,flag", NoteModel.class);
List<TreeNode> treeNodeList = new ArrayList<>();
for (NoteModel n : all) {
TreeNode treeNode = new TreeNode(n.getId().intValue(), n.getPid().intValue(), n.getTitle(), String.valueOf(n.getId()), String.valueOf(n.getId()));
treeNodeList.add(treeNode);
}
TreeBuild bb = new TreeBuild(treeNodeList);
List<TreeNode> collect = bb.buildTree();
return Result.succeed(JSONArray.parseArray(JSONArray.toJSONString(collect)));
}
@Get
@Mapping("/home")
public Result noteHome(Context ctx, @Path int type, @Path String search) throws Exception {
System.out.println(type);
System.out.println(search);
List<NoteModel> all = new ArrayList<>();
if (type == 0) {
all = ((DbTableQuery)((DbTableQuery)this.db.table("note").whereLk("context", "%" + search + "%")).andLk("title", "%" + search + "%")).selectList("id,pid,title,createtime,updatetime,viewtime,flag", NoteModel.class);
} else if (type == 1) {
all = ((DbTableQuery)((DbTableQuery)((DbTableQuery)this.db.table("note").whereEq("flag", Integer.valueOf(1))).orderByDesc("updatetime")).limit(20)).selectList("id,pid,title,createtime,updatetime,viewtime,flag", NoteModel.class);
} else if (type == 2) {
all = ((DbTableQuery)((DbTableQuery)((DbTableQuery)this.db.table("note").whereEq("flag", Integer.valueOf(1))).orderByDesc("createtime")).limit(20)).selectList("id,pid,title,createtime,updatetime,viewtime,flag", NoteModel.class);
} else if (type == 3) {
all = ((DbTableQuery)((DbTableQuery)((DbTableQuery)this.db.table("note").whereEq("flag", Integer.valueOf(1))).orderByDesc("viewtime")).limit(20)).selectList("id,pid,title,createtime,updatetime,viewtime,flag", NoteModel.class);
} else if (type == 4) {
all = ((DbTableQuery)((DbTableQuery)((DbTableQuery)this.db.table("note").whereEq("flag", Integer.valueOf(0))).orderByDesc("updatetime")).limit(10000)).selectList("id,pid,title,createtime,updatetime,viewtime,flag", NoteModel.class);
}
return Result.succeed(JSONArray.parseArray(JSONArray.toJSONString(all)));
}
@Get
@Mapping("/get")
public Result getNote(Context ctx, @Path int id) throws Exception {
NoteModel model = (NoteModel)((DbTableQuery)this.db.table("note").whereEq("id", Integer.valueOf(id))).selectItem("*", NoteModel.class);
String time = DateUtil.now();
System.out.println(time);
int flag = ((DbTableQuery)this.db.table("note").set("viewtime", time).whereEq("id", Integer.valueOf(id))).update();
System.out.println(flag);
log.info(JSONObject.toJSONString(model, new com.alibaba.fastjson2.JSONWriter.Feature[0]));
return Result.succeed(model);
}
@Get
@Mapping("/add")
public Result addNote(Context ctx, @Path int pid) throws Exception {
String userid = getUserInfoId(ctx);
if (null == userid)
return Result.failure(401);
NoteModel note = new NoteModel();
note.setPid(Integer.valueOf(pid));
note.setTitle("未命名Note");
note.setFlag(Integer.valueOf(1));
note.setCreatetime(DateUtil.now());
note.setContext("{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"未命名Note\",\"type\":\"text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}");
// note.setContext("{\"root\": {\"type\": \"root\", \"format\": \"\", \"indent\": 0, \"version\": 1, \"children\": [{\"type\": \"paragraph\", \"format\": \"\", \"indent\": 0, \"version\": 1, \"children\": [], \"direction\": null}], \"direction\": null}}");
this.db.table("note").setEntityIf(note, (k, v) -> Boolean.valueOf((v != null))).insert();
return Result.succeed("ok");
}
@Post
@Mapping("/update")
public Result updateNote(@Body NoteRequest noteRequest) throws SQLException {
NoteModel note = (NoteModel)((DbTableQuery)this.db.table("note").whereEq("id", noteRequest.getId())).selectItem("id,pid,title,createtime,updatetime,viewtime,flag", NoteModel.class);
note.setTitle(noteRequest.getTitle());
note.setUpdatetime(DateUtil.now());
String cc = noteRequest.getContext();
JSONObject ar = JSONObject.parseObject(cc);
note.setContext(ar.toJSONString());
int flag = ((DbTableQuery)this.db.table("note").set("title", noteRequest.getTitle()).set("updatetime", DateUtil.now()).set("context", ar.toJSONString()).whereEq("id", noteRequest.getId())).update();
log.info("updateNote+ flag");
HistoryModel history = new HistoryModel();
history.setNid(Integer.valueOf(noteRequest.getId().intValue()));
history.setTitle(noteRequest.getTitle());
history.setFlag(Integer.valueOf(1));
history.setCreatetime(DateUtil.now());
history.setContext(ar.toJSONString());
long his = this.db.table("history").setEntityIf(history, (k, v) -> Boolean.valueOf((v != null))).insert();
log.info("history+ his");
return Result.succeed("ok");
}
@Post
@Mapping("/delete")
public Result deleteNote(@Body NoteRequest noteRequest) throws SQLException {
int flag = ((DbTableQuery)this.db.table("note").set("title", noteRequest.getTitle()).set("flag", Integer.valueOf(0)).whereEq("id", noteRequest.getId())).update();
System.out.println(flag);
return Result.succeed("ok");
}
@Get
@Mapping("/deleteBack")
public Result deleteBack(@Path int id) throws Exception {
int flag = ((DbTableQuery)this.db.table("note").set("flag", Integer.valueOf(1)).whereEq("id", Integer.valueOf(id))).update();
System.out.println(flag);
return Result.succeed("ok");
}
@Get
@Mapping("/historyQueryOrDelete")
public Result historyQueryOrDelete(@Path int flag) throws Exception {
log.info("history+ flag" + flag);
if(flag==0){
long count = db.table("history").selectCount();
log.info("count:" + count);
return Result.succeed(count);
}else if(flag==1){
int flagdb = db.table("history").whereEq("flag",1).delete();
log.info("flagdb:" + flagdb);
return Result.succeed(0);
}
return null;
}
private String getUserInfoId(Context ctx) {
String userId = "";
if (null != ctx.header("Authorization")) {
String token = ctx.header("Authorization");
token = token.replace("Bearer ", "");
System.out.println("token:" + token);
Claims claims = JwtUtils.parseJwt(token);
System.out.println("claims:" + claims);
if (null != claims) {
System.out.println("username:" + claims.get("user_name"));
System.out.println("userid:" + claims.get("user_id"));
System.out.println("exp:" + claims.get("exp"));
userId = claims.get("user_id").toString();
return userId;
}
return null;
}
return null;
}
}
@@ -0,0 +1,34 @@
package com.cyynote.controller;
import com.cyynote.controller.BaseController;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Mapping;
@Controller
@Mapping("/api/test")
public class Test2Controller extends BaseController {
@Get
@Mapping("/all")
public String allAccess() {
return "Public Content.";
}
@Get
@Mapping("/user")
public String userAccess() {
return "User Content.";
}
@Get
@Mapping("/mod")
public String moderatorAccess() {
return "Moderator Board.";
}
@Get
@Mapping("/admin")
public String adminAccess() {
return "Admin Board.";
}
}
@@ -0,0 +1,26 @@
package com.cyynote.dso;
import java.util.ArrayList;
import java.util.List;
import org.noear.solon.auth.AuthProcessorBase;
public class AuthProcessorImpl extends AuthProcessorBase {
public boolean verifyLogined() {
return true;
}
protected List<String> getPermissions() {
List<String> list = new ArrayList<>();
list.add("user:add");
list.add("user:demo");
return list;
}
protected List<String> getRoles() {
List<String> list = new ArrayList<>();
list.add("admin1");
list.add("admin2");
return list;
}
}
@@ -0,0 +1,19 @@
package com.cyynote.dso;
import com.cyynote.model.UserModel;
import java.util.Map;
import org.noear.wood.BaseMapper;
import org.noear.wood.annotation.Db;
import org.noear.wood.annotation.Sql;
@Db
public interface AuthSqlAnnotation extends BaseMapper<UserModel> {
@Sql("select app_id from appx limit 1")
int user_get() throws Exception;
@Sql(value = "select * from user where id = @{id} limit 1", caching = "test", cacheTag = "app_${id}")
UserModel user_get2(int paramInt) throws Exception;
@Sql(value = "select * from ${tb} where id = @{id} limit 1", cacheClear = "test")
Map<String, Object> user_get3(String paramString, int paramInt) throws Exception;
}
@@ -0,0 +1,59 @@
package com.cyynote.dso;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
public class DsHelper {
private static boolean inited = false;
public static void initData(DataSource ds) {
if (inited)
return;
inited = true;
Connection conn = null;
try {
conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement("SELECT name FROM sqlite_master WHERE type='table' AND name='appx';");
ResultSet res = ps.executeQuery();
if (!res.next()) {
String[] sqls = getSqlFromFile();
for (String sql : sqls)
runSql(conn, sql);
}
ps.close();
} catch (SQLException sqlException) {
throw new RuntimeException(sqlException);
} finally {
try {
if (conn != null)
conn.close();
} catch (SQLException sQLException) {}
}
}
private static String[] getSqlFromFile() {
try {
InputStream ins = com.cyynote.dso.DsHelper.class.getResourceAsStream("/db/schema.sql");
int len = ins.available();
byte[] bs = new byte[len];
ins.read(bs);
String str = new String(bs, "UTF-8");
String[] sql = str.split(";");
return sql;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private static void runSql(Connection conn, String sql) throws SQLException {
System.out.println(sql);
PreparedStatement ps = conn.prepareStatement(sql);
ps.executeUpdate();
ps.close();
}
}
@@ -0,0 +1,32 @@
package com.cyynote.dso;
import com.cyynote.model.NoteModel;
import java.util.List;
import java.util.Map;
import org.noear.wood.BaseMapper;
import org.noear.wood.annotation.Db;
import org.noear.wood.annotation.Sql;
@Db
public interface NoteSqlAnnotation extends BaseMapper<NoteModel> {
@Sql("select id from note limit 1")
int note_get() throws Exception;
@Sql("select * from note where flag =1 limit 10000")
List<NoteModel> findAll() throws Exception;
@Sql(value = "select * from note where id = @{id} limit 1", caching = "test", cacheTag = "app_${id}")
NoteModel note_get2(int paramInt) throws Exception;
@Sql(value = "select * from ${tb} where id = @{id} limit 1", cacheClear = "test")
Map<String, Object> note_get3(String paramString, int paramInt) throws Exception;
@Sql("insert into note (`pid`,`title`,`context`,`createtime`,`flag`) values (@{pid},${title},${context},${createtime},@{flag})")
Map<String, Object> insert(int paramInt1, String paramString1, String paramString2, String paramString3, int paramInt2) throws Exception;
@Sql("update note set id = @{id} where id = @{id} ")
Map<String, Object> update(String paramString, int paramInt) throws Exception;
@Sql("update note set viewtime = @{viewtime} where id = @{id}")
Map<String, Object> updateViewtime(String paramString, int paramInt) throws Exception;
}
@@ -0,0 +1,26 @@
package com.cyynote.dso;
import com.cyynote.model.AppxModel;
import java.util.List;
import java.util.Map;
import org.noear.wood.BaseMapper;
import org.noear.wood.annotation.Db;
import org.noear.wood.annotation.Sql;
@Db
public interface SqlAnnotation extends BaseMapper<AppxModel> {
@Sql("select app_id from appx limit 1")
int appx_get() throws Exception;
@Sql(value = "select * from appx where app_id = @{app_id} limit 1", caching = "test", cacheTag = "app_${app_id}")
AppxModel appx_get2(int paramInt) throws Exception;
@Sql(value = "select * from ${tb} where app_id = @{app_id} limit 1", cacheClear = "test")
Map<String, Object> appx_get3(String paramString, int paramInt) throws Exception;
@Sql("select * from appx where app_id>@{app_id} order by app_id asc limit 4")
List<AppxModel> appx_getlist(int paramInt) throws Exception;
@Sql("select app_id from appx limit 4")
List<Integer> appx_getids() throws Exception;
}
@@ -0,0 +1,20 @@
package com.cyynote.dso;
import com.cyynote.model.AppxModel;
import java.util.List;
import java.util.Map;
import org.noear.wood.BaseMapper;
import org.noear.wood.xml.Namespace;
@Namespace("webapp.dso")
public interface SqlMapper extends BaseMapper<AppxModel> {
int appx_get() throws Exception;
AppxModel appx_get2(int paramInt) throws Exception;
Map<String, Object> appx_get3(String paramString, int paramInt) throws Exception;
List<AppxModel> appx_getlist(int paramInt) throws Exception;
List<Integer> appx_getids() throws Exception;
}
@@ -0,0 +1,17 @@
package com.cyynote.model;
import org.noear.wood.annotation.PrimaryKey;
public class Appx {
@PrimaryKey
public int app_id;
public int agroup_id;
public String note;
public String app_key;
public int ar_is_examine;
}
@@ -0,0 +1,20 @@
package com.cyynote.model;
import lombok.Getter;
import lombok.Setter;
import org.noear.wood.annotation.PrimaryKey;
import org.noear.wood.annotation.Table;
@Getter
@Setter
@Table("appx")
public class AppxModel {
@PrimaryKey
private int app_id;
private int agroup_id;
private String note;
private String app_key;
private int ar_is_examine;
}
@@ -0,0 +1,86 @@
package com.cyynote.model;
import lombok.Data;
import org.noear.wood.annotation.PrimaryKey;
import org.noear.wood.annotation.Table;
@Data
@Table("history")
public class HistoryModel {
@PrimaryKey
public Integer id;
public Integer nid;
public String title;
public String context;
public String conjson;
public String createtime;
public Integer flag;
public void setId(Integer id) {
this.id = id;
}
public void setNid(Integer nid) {
this.nid = nid;
}
public void setTitle(String title) {
this.title = title;
}
public void setContext(String context) {
this.context = context;
}
public void setConjson(String conjson) {
this.conjson = conjson;
}
public void setCreatetime(String createtime) {
this.createtime = createtime;
}
public void setFlag(Integer flag) {
this.flag = flag;
}
public String toString() {
return "HistoryModel(id=" + getId() + ", nid=" + getNid() + ", title=" + getTitle() + ", context=" + getContext() + ", conjson=" + getConjson() + ", createtime=" + getCreatetime() + ", flag=" + getFlag() + ")";
}
public Integer getId() {
return this.id;
}
public Integer getNid() {
return this.nid;
}
public String getTitle() {
return this.title;
}
public String getContext() {
return this.context;
}
public String getConjson() {
return this.conjson;
}
public String getCreatetime() {
return this.createtime;
}
public Integer getFlag() {
return this.flag;
}
}
@@ -0,0 +1,107 @@
package com.cyynote.model;
import lombok.Data;
import org.noear.wood.annotation.PrimaryKey;
import org.noear.wood.annotation.Table;
@Data
@Table("note")
public class NoteModel {
@PrimaryKey
public Integer id;
public Integer pid;
public String title;
public String context;
public String conjson;
public String createtime;
public String updatetime;
public String viewtime;
public Integer flag;
public void setId(Integer id) {
this.id = id;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public void setTitle(String title) {
this.title = title;
}
public void setContext(String context) {
this.context = context;
}
public void setConjson(String conjson) {
this.conjson = conjson;
}
public void setCreatetime(String createtime) {
this.createtime = createtime;
}
public void setUpdatetime(String updatetime) {
this.updatetime = updatetime;
}
public void setViewtime(String viewtime) {
this.viewtime = viewtime;
}
public void setFlag(Integer flag) {
this.flag = flag;
}
public String toString() {
return "NoteModel(id=" + getId() + ", pid=" + getPid() + ", title=" + getTitle() + ", context=" + getContext() + ", conjson=" + getConjson() + ", createtime=" + getCreatetime() + ", updatetime=" + getUpdatetime() + ", viewtime=" + getViewtime() + ", flag=" + getFlag() + ")";
}
public Integer getId() {
return this.id;
}
public Integer getPid() {
return this.pid;
}
public String getTitle() {
return this.title;
}
public String getContext() {
return this.context;
}
public String getConjson() {
return this.conjson;
}
public String getCreatetime() {
return this.createtime;
}
public String getUpdatetime() {
return this.updatetime;
}
public String getViewtime() {
return this.viewtime;
}
public Integer getFlag() {
return this.flag;
}
}
@@ -0,0 +1,85 @@
package com.cyynote.model;
import lombok.Data;
import org.noear.wood.annotation.PrimaryKey;
import org.noear.wood.annotation.Table;
@Data
@Table("user")
public class UserModel {
@PrimaryKey
public Integer id;
public String email;
public String password;
public String username;
public String role;
public String token;
public String logintime;
public void setId(Integer id) {
this.id = id;
}
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
public void setRole(String role) {
this.role = role;
}
public void setToken(String token) {
this.token = token;
}
public void setLogintime(String logintime) {
this.logintime = logintime;
}
public String toString() {
return "UserModel(id=" + getId() + ", email=" + getEmail() + ", password=" + getPassword() + ", username=" + getUsername() + ", role=" + getRole() + ", token=" + getToken() + ", logintime=" + getLogintime() + ")";
}
public Integer getId() {
return this.id;
}
public String getEmail() {
return this.email;
}
public String getPassword() {
return this.password;
}
public String getUsername() {
return this.username;
}
public String getRole() {
return this.role;
}
public String getToken() {
return this.token;
}
public String getLogintime() {
return this.logintime;
}
}
@@ -0,0 +1,25 @@
package com.cyynote.payload.request;
public class LoginRequest {
private String username;
private String password;
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
@@ -0,0 +1,44 @@
package com.cyynote.payload.request;
public class NoteRequest {
private Long id;
private Long pid;
private String title;
private String context;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getPid() {
return this.pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContext() {
return this.context;
}
public void setContext(String context) {
this.context = context;
}
}
@@ -0,0 +1,47 @@
package com.cyynote.payload.request;
import java.util.Set;
public class SignupRequest {
private String username;
private String email;
private Set<String> role;
private String password;
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<String> getRole() {
return this.role;
}
public void setRole(Set<String> role) {
this.role = role;
}
}
@@ -0,0 +1,17 @@
package com.cyynote.payload.request;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class UpdatePasswordRequest {
private String username;
private String oldpassword;
private String newpassword;
}
@@ -0,0 +1,70 @@
package com.cyynote.payload.response;
import java.util.List;
public class JwtResponse {
private String token;
private String type = "Bearer";
private Long id;
private String username;
private String email;
private List<String> roles;
public JwtResponse(String accessToken, Long id, String username, String email, List<String> roles) {
this.token = accessToken;
this.id = id;
this.username = username;
this.email = email;
this.roles = roles;
}
public String getAccessToken() {
return this.token;
}
public void setAccessToken(String accessToken) {
this.token = accessToken;
}
public String getTokenType() {
return this.type;
}
public void setTokenType(String tokenType) {
this.type = tokenType;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public List<String> getRoles() {
return this.roles;
}
}
@@ -0,0 +1,17 @@
package com.cyynote.payload.response;
public class MessageResponse {
private String message;
public MessageResponse(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
}
@@ -0,0 +1,42 @@
package com.cyynote.util;
import com.cyynote.util.TreeNode;
import java.util.ArrayList;
import java.util.List;
public class TreeBuild {
public List<TreeNode> nodeList = new ArrayList<>();
public TreeBuild(List<TreeNode> nodeList) {
this.nodeList = nodeList;
}
public List<TreeNode> getRootNode() {
List<TreeNode> rootNodeList = new ArrayList<>();
for (TreeNode treeNode : this.nodeList) {
if (0 == treeNode.getPid())
rootNodeList.add(treeNode);
}
return rootNodeList;
}
public List<TreeNode> buildTree() {
List<TreeNode> treeNodes = new ArrayList<>();
for (TreeNode treeRootNode : getRootNode()) {
treeRootNode = buildChildTree(treeRootNode);
treeNodes.add(treeRootNode);
}
return treeNodes;
}
public TreeNode buildChildTree(TreeNode pNode) {
List<TreeNode> childTree = new ArrayList<>();
for (TreeNode treeNode : this.nodeList) {
if (treeNode.getPid() == pNode.getId())
childTree.add(buildChildTree(treeNode));
}
pNode.setChildren(childTree);
return pNode;
}
}
@@ -0,0 +1,74 @@
package com.cyynote.util;
import java.util.List;
public class TreeNode {
private int id;
private int pid;
private String label;
private String value;
private String key;
private List<com.cyynote.util.TreeNode> children;
public TreeNode(int id, int pid, String label, String value, String key) {
this.id = id;
this.pid = pid;
this.label = label;
this.value = value;
this.key = key;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public int getPid() {
return this.pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getLabel() {
return this.label;
}
public void setLabel(String label) {
this.label = label;
}
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
public String getKey() {
return this.key;
}
public void setKey(String key) {
this.key = key;
}
public List<com.cyynote.util.TreeNode> getChildren() {
return this.children;
}
public void setChildren(List<com.cyynote.util.TreeNode> children) {
this.children = children;
}
}
@@ -0,0 +1,3 @@
test.db1:
jdbcUrl: "jdbc:sqlite:D:/cyynote.db"
driverClassName: "org.sqlite.JDBC"
@@ -0,0 +1,4 @@
test.db1:
jdbcUrl: "jdbc:sqlite:/opt/db/cyynote.db"
driverClassName: "org.sqlite.JDBC"
@@ -0,0 +1,23 @@
server.port: 8080
solon.app:
name: demoapp
group: demo
# 基于 header 传(适合接口开发,每次会自动输出[可改为手动])
solon.env: dev
solon.output.meta: 1
server.session:
timeout: 7200 #单位秒;(可不配,默认:7200
state:
jwt:
name: TOKEN #变量名;(可不配,默认:TOKEN
secret: "E3F9N2kRDQf55pnJPnFoo5+ylKmZQ7AXmWeOVPKbEd8=" #密钥(使用 JwtUtils.createKey() 生成);(可不配,默认:xxx)
prefix: Bearer #令牌前缀(可不配,默认:空)
allowExpire: true #充许超时;(可不配,默认:true);false,则token一直有效
allowAutoIssue: true #充许自动输出;(可不配,默认:true);flase,则不向header 或 cookie 设置值(由用户手动控制)
allowUseHeader: true #充许使用Header传递;(可不配,默认:使用 Cookie 传递);true,则使用 header 传递
@@ -0,0 +1,53 @@
CREATE TABLE `user` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT,
password TEXT,
username TEXT,
role TEXT,
token TEXT,
logintime TEXT
);
CREATE TABLE `note` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
pid INTEGER,
title TEXT,
context TEXT,
conjson TEXT,
createtime TEXT,
updatetime TEXT,
viewtime TEXT,
userid INTEGER,
username TEXT,
flag INTEGER DEFAULT 1
);
CREATE TABLE `history` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nid INTEGER,
title TEXT,
context TEXT,
conjson TEXT,
createtime TEXT,
userid INTEGER,
username TEXT
);
CREATE TABLE appx (
app_id INTEGER PRIMARY KEY AUTOINCREMENT,
app_key TEXT,
akey TEXT,
ugroup_id INTEGER DEFAULT 0,
agroup_id INTEGER,
name TEXT,
note TEXT,
ar_is_setting INTEGER NOT NULL DEFAULT 0,
ar_is_examine INTEGER NOT NULL DEFAULT 0,
ar_examine_ver INTEGER NOT NULL DEFAULT 0,
log_fulltime TEXT
);
INSERT INTO `user` VALUES ('1', 'aaaaaaaaa', 'cyy123', 'admin', 'admin','','');
INSERT INTO `user` VALUES ('2', 'aaaaaaaaa', 'test', 'test', 'test','','');
INSERT INTO `note` VALUES ('1', '0', 'test', 'test', 'test','','','','1','1','1');
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<mapper namespace="webapp.dso"
db="db">
<sql id="appx_get" return="int" remarks="随便取条数据的ID">
select app_id from appx limit 1
</sql>
<sql id="appx_get0" return="Integer" remarks="随便取条数据的ID">
<![CDATA[
select app_id from appx where app_id < 1 limit 1
]]>
</sql>
<sql id="appx_get2" return="AppxModel" remarks="根据id取条数据">
select * from appx where app_id = @{app_id:int} limit 1
</sql>
<sql id="appx_getlist" return="List[AppxModel]">
select * from appx where app_id > @{app_id:int} order by app_id asc limit 4
</sql>
<sql id="appx_getids" return="List[Integer]">
select app_id from appx limit 4
</sql>
<sql id="appx_getids2" return="Set[Integer]">
select app_id from appx limit 4
</sql>
</mapper>
@@ -0,0 +1,3 @@
test.db1:
jdbcUrl: "jdbc:sqlite:D:/cyynote.db"
driverClassName: "org.sqlite.JDBC"
@@ -0,0 +1,4 @@
test.db1:
jdbcUrl: "jdbc:sqlite:/opt/db/cyynote.db"
driverClassName: "org.sqlite.JDBC"
+23
View File
@@ -0,0 +1,23 @@
server.port: 8080
solon.app:
name: demoapp
group: demo
# 基于 header 传(适合接口开发,每次会自动输出[可改为手动])
solon.env: dev
solon.output.meta: 1
server.session:
timeout: 7200 #单位秒;(可不配,默认:7200
state:
jwt:
name: TOKEN #变量名;(可不配,默认:TOKEN
secret: "E3F9N2kRDQf55pnJPnFoo5+ylKmZQ7AXmWeOVPKbEd8=" #密钥(使用 JwtUtils.createKey() 生成);(可不配,默认:xxx)
prefix: Bearer #令牌前缀(可不配,默认:空)
allowExpire: true #充许超时;(可不配,默认:true);false,则token一直有效
allowAutoIssue: true #充许自动输出;(可不配,默认:true);flase,则不向header 或 cookie 设置值(由用户手动控制)
allowUseHeader: true #充许使用Header传递;(可不配,默认:使用 Cookie 传递);true,则使用 header 传递
@@ -0,0 +1,53 @@
CREATE TABLE `user` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT,
password TEXT,
username TEXT,
role TEXT,
token TEXT,
logintime TEXT
);
CREATE TABLE `note` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
pid INTEGER,
title TEXT,
context TEXT,
conjson TEXT,
createtime TEXT,
updatetime TEXT,
viewtime TEXT,
userid INTEGER,
username TEXT,
flag INTEGER DEFAULT 1
);
CREATE TABLE `history` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nid INTEGER,
title TEXT,
context TEXT,
conjson TEXT,
createtime TEXT,
userid INTEGER,
username TEXT
);
CREATE TABLE appx (
app_id INTEGER PRIMARY KEY AUTOINCREMENT,
app_key TEXT,
akey TEXT,
ugroup_id INTEGER DEFAULT 0,
agroup_id INTEGER,
name TEXT,
note TEXT,
ar_is_setting INTEGER NOT NULL DEFAULT 0,
ar_is_examine INTEGER NOT NULL DEFAULT 0,
ar_examine_ver INTEGER NOT NULL DEFAULT 0,
log_fulltime TEXT
);
INSERT INTO `user` VALUES ('1', 'aaaaaaaaa', 'cyy123', 'admin', 'admin','','');
INSERT INTO `user` VALUES ('2', 'aaaaaaaaa', 'test', 'test', 'test','','');
INSERT INTO `note` VALUES ('1', '0', 'test', 'test', 'test','','','','1','1','1');
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<mapper namespace="webapp.dso"
db="db">
<sql id="appx_get" return="int" remarks="随便取条数据的ID">
select app_id from appx limit 1
</sql>
<sql id="appx_get0" return="Integer" remarks="随便取条数据的ID">
<![CDATA[
select app_id from appx where app_id < 1 limit 1
]]>
</sql>
<sql id="appx_get2" return="AppxModel" remarks="根据id取条数据">
select * from appx where app_id = @{app_id:int} limit 1
</sql>
<sql id="appx_getlist" return="List[AppxModel]">
select * from appx where app_id > @{app_id:int} order by app_id asc limit 4
</sql>
<sql id="appx_getids" return="List[Integer]">
select app_id from appx limit 4
</sql>
<sql id="appx_getids2" return="Set[Integer]">
select app_id from appx limit 4
</sql>
</mapper>
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,5 @@
#Generated by Maven
#Wed Feb 05 19:29:06 CST 2025
groupId=com.cyynote
artifactId=cyynote
version=1.0.0
@@ -0,0 +1,27 @@
com\cyynote\payload\request\UpdatePasswordRequest.class
com\cyynote\controller\BaseController.class
com\cyynote\dso\DsHelper.class
com\cyynote\model\HistoryModel.class
com\cyynote\model\Appx.class
com\cyynote\payload\request\SignupRequest.class
com\cyynote\dso\AuthProcessorImpl.class
com\cyynote\controller\Test2Controller.class
com\cyynote\payload\response\MessageResponse.class
com\cyynote\WebApp.class
com\cyynote\dso\AuthSqlAnnotation.class
com\cyynote\controller\JwtInterceptor.class
com\cyynote\model\AppxModel.class
com\cyynote\controller\DemoController.class
com\cyynote\Config.class
com\cyynote\util\TreeBuild.class
com\cyynote\dso\SqlMapper.class
com\cyynote\model\UserModel.class
com\cyynote\payload\response\JwtResponse.class
com\cyynote\dso\NoteSqlAnnotation.class
com\cyynote\payload\request\LoginRequest.class
com\cyynote\controller\NoteController.class
com\cyynote\payload\request\NoteRequest.class
com\cyynote\util\TreeNode.class
com\cyynote\model\NoteModel.class
com\cyynote\dso\SqlAnnotation.class
com\cyynote\controller\AuthController.class
@@ -0,0 +1,27 @@
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\Config.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\controller\AuthController.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\controller\BaseController.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\controller\DemoController.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\controller\JwtInterceptor.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\controller\NoteController.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\controller\Test2Controller.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\dso\AuthProcessorImpl.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\dso\AuthSqlAnnotation.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\dso\DsHelper.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\dso\NoteSqlAnnotation.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\dso\SqlAnnotation.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\dso\SqlMapper.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\model\Appx.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\model\AppxModel.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\model\HistoryModel.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\model\NoteModel.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\model\UserModel.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\payload\request\LoginRequest.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\payload\request\NoteRequest.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\payload\request\SignupRequest.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\payload\request\UpdatePasswordRequest.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\payload\response\JwtResponse.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\payload\response\MessageResponse.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\util\TreeBuild.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\util\TreeNode.java
D:\chuyy_code\cyynote\cyynote-backend\src\main\java\com\cyynote\WebApp.java
+18
View File
@@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
+24
View File
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
+30
View File
@@ -0,0 +1,30 @@
# React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
## Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
- Configure the top-level `parserOptions` property like this:
```js
export default {
// other rules...
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},
}
```
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
Binary file not shown.
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" href="https://s11.ax1x.com/2023/12/19/piIwxyt.png">
<title>CyyNote</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
+80
View File
@@ -0,0 +1,80 @@
{
"name": "cyynote",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@alkhipce/editorjs-react": "^0.1.4",
"@blocknote/core": "^0.10.0",
"@blocknote/react": "^0.10.0",
"@douyinfe/semi-icons": "^2.48.0",
"@douyinfe/semi-icons-lab": "^2.48.0",
"@douyinfe/semi-ui": "^2.48.0",
"@editorjs/checklist": "^1.6.0",
"@editorjs/code": "^2.9.0",
"@editorjs/delimiter": "^1.4.0",
"@editorjs/editorjs": "^2.28.2",
"@editorjs/embed": "^2.7.0",
"@editorjs/header": "^2.8.1",
"@editorjs/image": "^2.9.0",
"@editorjs/inline-code": "^1.5.0",
"@editorjs/link": "^2.6.2",
"@editorjs/list": "^1.9.0",
"@editorjs/marker": "^1.4.0",
"@editorjs/paragraph": "^2.11.3",
"@editorjs/quote": "^2.6.0",
"@editorjs/raw": "^2.5.0",
"@editorjs/simple-image": "^1.6.0",
"@editorjs/table": "^2.3.0",
"@editorjs/warning": "^1.4.0",
"@excalidraw/excalidraw": "^0.17.2",
"@lexical/clipboard": "^0.12.5",
"@lexical/code": "^0.12.5",
"@lexical/file": "^0.12.5",
"@lexical/hashtag": "^0.12.5",
"@lexical/link": "^0.12.5",
"@lexical/list": "^0.12.5",
"@lexical/mark": "^0.12.5",
"@lexical/overflow": "^0.12.5",
"@lexical/plain-text": "^0.12.5",
"@lexical/react": "^0.12.5",
"@lexical/rich-text": "^0.12.5",
"@lexical/selection": "^0.12.5",
"@lexical/table": "^0.12.5",
"@lexical/utils": "^0.12.5",
"axios": "^1.6.2",
"editorjs-html": "^3.4.3",
"formik": "^2.4.5",
"html-react-parser": "^5.0.7",
"katex": "^0.16.9",
"lexical": "^0.12.5",
"prettier": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-editor-js": "^2.1.0",
"react-router-dom": "^6.20.1",
"sass": "^1.69.5",
"y-websocket": "^1.5.0",
"yjs": "^13.6.10",
"yup": "^1.3.2"
},
"devDependencies": {
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser": "^6.10.0",
"@vitejs/plugin-react": "^4.2.0",
"eslint": "^8.53.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.4",
"typescript": "^5.2.2",
"vite": "^5.0.0"
}
}
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+42
View File
@@ -0,0 +1,42 @@
/*#root {*/
/* max-width: 1280px;*/
/* margin: 0 auto;*/
/* padding: 2rem;*/
/* text-align: center;*/
/*}*/
/*.logo {*/
/* height: 6em;*/
/* padding: 1.5em;*/
/* will-change: filter;*/
/* transition: filter 300ms;*/
/*}*/
/*.logo:hover {*/
/* filter: drop-shadow(0 0 2em #646cffaa);*/
/*}*/
/*.logo.react:hover {*/
/* filter: drop-shadow(0 0 2em #61dafbaa);*/
/*}*/
/*@keyframes logo-spin {*/
/* from {*/
/* transform: rotate(0deg);*/
/* }*/
/* to {*/
/* transform: rotate(360deg);*/
/* }*/
/*}*/
/*@media (prefers-reduced-motion: no-preference) {*/
/* a:nth-of-type(2) .logo {*/
/* animation: logo-spin infinite 20s linear;*/
/* }*/
/*}*/
/*.card {*/
/* padding: 2em;*/
/*}*/
/*.read-the-docs {*/
/* color: #888;*/
/*}*/
+163
View File
@@ -0,0 +1,163 @@
import { Component } from "react";
import { Routes, Route } from "react-router-dom";
import "./App.css";
import AuthService from "./services/auth.service";
import IUser from './types/user.type';
// import Login from "./components/login.component";
import Register from "./components/register.component";
// import Home from "./components/home.component";
import Profile from "./components/profile.component";
import BoardUser from "./components/board-user.component";
import BoardModerator from "./components/board-moderator.component";
import BoardAdmin from "./components/board-admin.component";
import NotePage from "./pages/note-page.tsx";
import EventBus from "./common/EventBus";
import SignIn from "./pages/sign-in.tsx";
import Test from "./pages/test.tsx";
// "build": "tsc && vite build",
type Props = {};
type State = {
showModeratorBoard: boolean,
showAdminBoard: boolean,
currentUser: IUser | undefined
}
class App extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.logOut = this.logOut.bind(this);
this.state = {
showModeratorBoard: false,
showAdminBoard: false,
currentUser: undefined,
};
}
componentDidMount() {
const user = AuthService.getCurrentUser();
if (user) {
this.setState({
currentUser: user,
showModeratorBoard: user.roles.includes("ROLE_MODERATOR"),
showAdminBoard: user.roles.includes("ROLE_ADMIN"),
});
}
EventBus.on("logout", this.logOut);
}
componentWillUnmount() {
EventBus.remove("logout", this.logOut);
}
logOut() {
AuthService.logout();
this.setState({
showModeratorBoard: false,
showAdminBoard: false,
currentUser: undefined,
});
}
render() {
// const { currentUser, showModeratorBoard, showAdminBoard } = this.state;
return (
<div>
{/*<nav className="navbar navbar-expand navbar-dark bg-dark">*/}
{/* <Link to={"/"} className="navbar-brand">*/}
{/* bezKoder*/}
{/* </Link>*/}
{/* <div className="navbar-nav mr-auto">*/}
{/* <li className="nav-item">*/}
{/* <Link to={"/home"} className="nav-link">*/}
{/* Home*/}
{/* </Link>*/}
{/* </li>*/}
{/* {showModeratorBoard && (*/}
{/* <li className="nav-item">*/}
{/* <Link to={"/mod"} className="nav-link">*/}
{/* Moderator Board*/}
{/* </Link>*/}
{/* </li>*/}
{/* )}*/}
{/* {showAdminBoard && (*/}
{/* <li className="nav-item">*/}
{/* <Link to={"/admin"} className="nav-link">*/}
{/* Admin Board*/}
{/* </Link>*/}
{/* </li>*/}
{/* )}*/}
{/* {currentUser && (*/}
{/* <li className="nav-item">*/}
{/* <Link to={"/user"} className="nav-link">*/}
{/* User*/}
{/* </Link>*/}
{/* </li>*/}
{/* )}*/}
{/* </div>*/}
{/* {currentUser ? (*/}
{/* <div className="navbar-nav ml-auto">*/}
{/* <li className="nav-item">*/}
{/* <Link to={"/profile"} className="nav-link">*/}
{/* {currentUser.username}*/}
{/* </Link>*/}
{/* </li>*/}
{/* <li className="nav-item">*/}
{/* <a href="/login" className="nav-link" onClick={this.logOut}>*/}
{/* LogOut*/}
{/* </a>*/}
{/* </li>*/}
{/* </div>*/}
{/* ) : (*/}
{/* <div className="navbar-nav ml-auto">*/}
{/* <li className="nav-item">*/}
{/* <Link to={"/login"} className="nav-link">*/}
{/* Login*/}
{/* </Link>*/}
{/* </li>*/}
{/* <li className="nav-item">*/}
{/* <Link to={"/register"} className="nav-link">*/}
{/* Sign Up*/}
{/* </Link>*/}
{/* </li>*/}
{/* </div>*/}
{/* )}*/}
{/*</nav>*/}
<div className="">
<Routes>
<Route path="/" element={<NotePage />} />
<Route path="/home" element={<NotePage />} />
<Route path="/login" element={<SignIn />} />
<Route path="/test" element={<Test />} />
<Route path="/register" element={<Register />} />
<Route path="/profile" element={<Profile />} />
<Route path="/user" element={<BoardUser />} />
<Route path="/mod" element={<BoardModerator />} />
<Route path="/admin" element={<BoardAdmin />} />
</Routes>
</div>
{ /*<AuthVerify logOut={this.logOut}/> */}
</div>
);
}
}
export default App;
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

+13
View File
@@ -0,0 +1,13 @@
const eventBus = {
on(event: string, callback: EventListener) {
document.addEventListener(event, (e) => callback(e));
},
dispatch(event: string, data?: any) {
document.dispatchEvent(new CustomEvent(event, { detail: data }));
},
remove(event: string, callback: EventListener) {
document.removeEventListener(event, callback);
},
};
export default eventBus;
@@ -0,0 +1,54 @@
import { Component } from "react";
import UserService from "../services/user.service";
import EventBus from "../common/EventBus";
type Props = {};
type State = {
content: string;
}
export default class BoardAdmin extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
content: ""
};
}
componentDidMount() {
UserService.getAdminBoard().then(
response => {
this.setState({
content: response.data
});
},
error => {
this.setState({
content:
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString()
});
if (error.response && error.response.status === 401) {
EventBus.dispatch("logout");
}
}
);
}
render() {
return (
<div className="container">
<header className="jumbotron">
<h3>{this.state.content}</h3>
</header>
</div>
);
}
}
@@ -0,0 +1,54 @@
import { Component } from "react";
import UserService from "../services/user.service";
import EventBus from "../common/EventBus";
type Props = {};
type State = {
content: string;
}
export default class BoardAdmin extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
content: ""
};
}
componentDidMount() {
UserService.getModeratorBoard().then(
response => {
this.setState({
content: response.data
});
},
error => {
this.setState({
content:
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString()
});
if (error.response && error.response.status === 401) {
EventBus.dispatch("logout");
}
}
);
}
render() {
return (
<div className="container">
<header className="jumbotron">
<h3>{this.state.content}</h3>
</header>
</div>
);
}
}
@@ -0,0 +1,54 @@
import { Component } from "react";
import UserService from "../services/user.service";
import EventBus from "../common/EventBus";
type Props = {};
type State = {
content: string;
}
export default class BoardUser extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
content: ""
};
}
componentDidMount() {
UserService.getUserBoard().then(
response => {
this.setState({
content: response.data
});
},
error => {
this.setState({
content:
(error.response &&
error.response.data &&
error.response.data.message) ||
error.message ||
error.toString()
});
if (error.response && error.response.status === 401) {
EventBus.dispatch("logout");
}
}
);
}
render() {
return (
<div className="container">
<header className="jumbotron">
<h3>{this.state.content}</h3>
</header>
</div>
);
}
}
@@ -0,0 +1,47 @@
import { Component } from "react";
import UserService from "../services/user.service";
type Props = {};
type State = {
content: string;
}
export default class Home extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
content: ""
};
}
componentDidMount() {
UserService.getPublicContent().then(
response => {
this.setState({
content: response.data
});
},
error => {
this.setState({
content:
(error.response && error.response.data) ||
error.message ||
error.toString()
});
}
);
}
render() {
return (
<div className="container">
<header className="jumbotron">
<h3>{this.state.content}</h3>
</header>
</div>
);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,278 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import {AutoFocusPlugin} from '@lexical/react/LexicalAutoFocusPlugin';
import {CharacterLimitPlugin} from '@lexical/react/LexicalCharacterLimitPlugin';
import {CheckListPlugin} from '@lexical/react/LexicalCheckListPlugin';
import {ClearEditorPlugin} from '@lexical/react/LexicalClearEditorPlugin';
import LexicalClickableLinkPlugin from '@lexical/react/LexicalClickableLinkPlugin';
import {CollaborationPlugin} from '@lexical/react/LexicalCollaborationPlugin';
import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary';
import {HashtagPlugin} from '@lexical/react/LexicalHashtagPlugin';
import {HistoryPlugin} from '@lexical/react/LexicalHistoryPlugin';
import {HorizontalRulePlugin} from '@lexical/react/LexicalHorizontalRulePlugin';
import {ListPlugin} from '@lexical/react/LexicalListPlugin';
import {PlainTextPlugin} from '@lexical/react/LexicalPlainTextPlugin';
import {RichTextPlugin} from '@lexical/react/LexicalRichTextPlugin';
import {TabIndentationPlugin} from '@lexical/react/LexicalTabIndentationPlugin';
import {TablePlugin} from '@lexical/react/LexicalTablePlugin';
import useLexicalEditable from '@lexical/react/useLexicalEditable';
import {useEffect, useState,useLayoutEffect} from 'react';
import {CAN_USE_DOM} from './shared/src/canUseDOM';
import {createWebsocketProvider} from './collaboration';
import {useSettings} from './context/SettingsContext';
import {useSharedHistoryContext} from './context/SharedHistoryContext';
import ActionsPlugin from './plugins/ActionsPlugin';
import AutocompletePlugin from './plugins/AutocompletePlugin';
import AutoEmbedPlugin from './plugins/AutoEmbedPlugin';
import AutoLinkPlugin from './plugins/AutoLinkPlugin';
import CodeActionMenuPlugin from './plugins/CodeActionMenuPlugin';
import CodeHighlightPlugin from './plugins/CodeHighlightPlugin';
import CollapsiblePlugin from './plugins/CollapsiblePlugin';
import CommentPlugin from './plugins/CommentPlugin';
import ComponentPickerPlugin from './plugins/ComponentPickerPlugin';
import ContextMenuPlugin from './plugins/ContextMenuPlugin';
import DragDropPaste from './plugins/DragDropPastePlugin';
import DraggableBlockPlugin from './plugins/DraggableBlockPlugin';
import EmojiPickerPlugin from './plugins/EmojiPickerPlugin';
import EmojisPlugin from './plugins/EmojisPlugin';
import EquationsPlugin from './plugins/EquationsPlugin';
import ExcalidrawPlugin from './plugins/ExcalidrawPlugin';
import FigmaPlugin from './plugins/FigmaPlugin';
import FloatingLinkEditorPlugin from './plugins/FloatingLinkEditorPlugin';
import FloatingTextFormatToolbarPlugin from './plugins/FloatingTextFormatToolbarPlugin';
import ImagesPlugin from './plugins/ImagesPlugin';
import InlineImagePlugin from './plugins/InlineImagePlugin';
import KeywordsPlugin from './plugins/KeywordsPlugin';
import {LayoutPlugin} from './plugins/LayoutPlugin/LayoutPlugin';
import LinkPlugin from './plugins/LinkPlugin';
import ListMaxIndentLevelPlugin from './plugins/ListMaxIndentLevelPlugin';
import MarkdownShortcutPlugin from './plugins/MarkdownShortcutPlugin';
import {MaxLengthPlugin} from './plugins/MaxLengthPlugin';
import MentionsPlugin from './plugins/MentionsPlugin';
import PageBreakPlugin from './plugins/PageBreakPlugin';
import PollPlugin from './plugins/PollPlugin';
import SpeechToTextPlugin from './plugins/SpeechToTextPlugin';
import TabFocusPlugin from './plugins/TabFocusPlugin';
import TableCellActionMenuPlugin from './plugins/TableActionMenuPlugin';
import TableCellResizer from './plugins/TableCellResizer';
import TableOfContentsPlugin from './plugins/TableOfContentsPlugin';
import ToolbarPlugin from './plugins/ToolbarPlugin';
import TreeViewPlugin from './plugins/TreeViewPlugin';
import TwitterPlugin from './plugins/TwitterPlugin';
import YouTubePlugin from './plugins/YouTubePlugin';
import ContentEditable from './ui/ContentEditable';
import Placeholder from './ui/Placeholder';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import GlobalEventsPlugin from "./plugins/GlobalEventsPlugin";
const skipCollaborationInit =
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
window.parent != null && window.parent.frames.right === window;
function OnChangePlugin({ onChange }) {
const [editor] = useLexicalComposerContext();
useEffect(() => {
return editor.registerUpdateListener(({editorState}) => {
onChange(editorState);
});
}, [editor, onChange]);
}
export default function Editor(props: { noteId: bigint; noteTitle: string; editData: any; handleLawClick_item2: any; }): JSX.Element {
const [editor] = useLexicalComposerContext();
console.log(props.noteId)
const {historyState} = useSharedHistoryContext();
const {
settings: {
isCollab,
isAutocomplete,
isMaxLength,
isCharLimit,
isCharLimitUtf8,
isRichText,
showTreeView,
showTableOfContents,
shouldUseLexicalContextMenu,
tableCellMerge,
tableCellBackgroundColor,
},
} = useSettings();
const isEditable = useLexicalEditable();
const text = isCollab
? 'Enter some collaborative rich text...'
: isRichText
? 'Enter some rich text...'
: 'Enter some plain text...';
const placeholder = <Placeholder>{text}</Placeholder>;
const [floatingAnchorElem, setFloatingAnchorElem] =
useState<HTMLDivElement | null>(null);
const [isSmallWidthViewport, setIsSmallWidthViewport] =
useState<boolean>(false);
const [isLinkEditMode, setIsLinkEditMode] = useState<boolean>(false);
const [editorState, setEditorState] = useState();
const onRef = (_floatingAnchorElem: HTMLDivElement) => {
if (_floatingAnchorElem !== null) {
setFloatingAnchorElem(_floatingAnchorElem);
}
};
useEffect(() => {
const updateViewPortWidth = () => {
const isNextSmallWidthViewport =
CAN_USE_DOM && window.matchMedia('(max-width: 1025px)').matches;
if (isNextSmallWidthViewport !== isSmallWidthViewport) {
setIsSmallWidthViewport(isNextSmallWidthViewport);
}
};
updateViewPortWidth();
window.addEventListener('resize', updateViewPortWidth);
return () => {
window.removeEventListener('resize', updateViewPortWidth);
};
}, [isSmallWidthViewport]);
function onChange(editorState) {
// Call toJSON on the EditorState object, which produces a serialization safe string
const editorStateJSON = editorState.toJSON();
// However, we still have a JavaScript object, so we need to convert it to an actual string with JSON.stringify
setEditorState(JSON.stringify(editorStateJSON));
}
console.log(props.noteId)
// console.log(props.editData)
return (
<>
{isRichText && <ToolbarPlugin setIsLinkEditMode={setIsLinkEditMode} />}
<div
className={`editor-container ${showTreeView ? 'tree-view' : ''} ${
!isRichText ? 'plain-text' : ''
}`}>
{isMaxLength && <MaxLengthPlugin maxLength={30} />}
<DragDropPaste />
<AutoFocusPlugin />
<ClearEditorPlugin />
<ComponentPickerPlugin />
<EmojiPickerPlugin />
<AutoEmbedPlugin />
<MentionsPlugin />
<EmojisPlugin />
<HashtagPlugin />
<KeywordsPlugin />
<SpeechToTextPlugin />
<AutoLinkPlugin />
<CommentPlugin
providerFactory={isCollab ? createWebsocketProvider : undefined}
/>
{isRichText ? (
<>
{isCollab ? (
<CollaborationPlugin
id="main"
providerFactory={createWebsocketProvider}
shouldBootstrap={!skipCollaborationInit}
/>
) : (
<HistoryPlugin externalHistoryState={historyState} />
)}
<RichTextPlugin
contentEditable={
<div className="editor-scroller">
<div className="editor" ref={onRef}>
<ContentEditable />
</div>
</div>
}
placeholder={placeholder}
ErrorBoundary={LexicalErrorBoundary}
/>
<MarkdownShortcutPlugin />
<CodeHighlightPlugin />
<ListPlugin />
<CheckListPlugin />
<ListMaxIndentLevelPlugin maxDepth={7} />
<TablePlugin
hasCellMerge={tableCellMerge}
hasCellBackgroundColor={tableCellBackgroundColor}
/>
<TableCellResizer />
<ImagesPlugin />
<InlineImagePlugin />
<LinkPlugin />
<PollPlugin />
<TwitterPlugin />
<YouTubePlugin />
<FigmaPlugin />
{!isEditable && <LexicalClickableLinkPlugin />}
<HorizontalRulePlugin />
<EquationsPlugin />
<ExcalidrawPlugin />
<TabFocusPlugin />
<TabIndentationPlugin />
<CollapsiblePlugin />
<PageBreakPlugin />
<LayoutPlugin />
<OnChangePlugin onChange={onChange}/>
<GlobalEventsPlugin />
{floatingAnchorElem && !isSmallWidthViewport && (
<>
<DraggableBlockPlugin anchorElem={floatingAnchorElem} />
<CodeActionMenuPlugin anchorElem={floatingAnchorElem} />
<FloatingLinkEditorPlugin
anchorElem={floatingAnchorElem}
isLinkEditMode={isLinkEditMode}
setIsLinkEditMode={setIsLinkEditMode}
/>
<TableCellActionMenuPlugin
anchorElem={floatingAnchorElem}
cellMerge={true}
/>
<FloatingTextFormatToolbarPlugin
anchorElem={floatingAnchorElem}
/>
</>
)}
</>
) : (
<>
<PlainTextPlugin
contentEditable={<ContentEditable />}
placeholder={placeholder}
ErrorBoundary={LexicalErrorBoundary}
/>
<HistoryPlugin externalHistoryState={historyState} />
</>
)}
{(isCharLimit || isCharLimitUtf8) && (
<CharacterLimitPlugin
charset={isCharLimit ? 'UTF-16' : 'UTF-8'}
maxLength={5}
/>
)}
{isAutocomplete && <AutocompletePlugin />}
<div>{showTableOfContents && <TableOfContentsPlugin />}</div>
{shouldUseLexicalContextMenu && <ContextMenuPlugin />}
<ActionsPlugin isRichText={isRichText} noteId={props.noteId} noteTitle={props.noteTitle} editData ={props.editData} handleLawClick_item3={props.handleLawClick_item2}/>
</div>
{showTreeView && <TreeViewPlugin />}
</>
);
}
@@ -0,0 +1,210 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import "./index.css";
import {$createLinkNode} from '@lexical/link';
import {$createListItemNode, $createListNode} from '@lexical/list';
import {LexicalComposer} from '@lexical/react/LexicalComposer';
import {$createHeadingNode, $createQuoteNode} from '@lexical/rich-text';
import {$createParagraphNode, $createTextNode, $getRoot} from 'lexical';
import {isDevPlayground} from './appSettings';
import {SettingsContext, useSettings} from './context/SettingsContext';
import {SharedAutocompleteContext} from './context/SharedAutocompleteContext';
import {SharedHistoryContext} from './context/SharedHistoryContext';
import Editor from './Editor';
import logo from './images/logo.svg';
import PlaygroundNodes from './nodes/PlaygroundNodes';
import DocsPlugin from './plugins/DocsPlugin';
import PasteLogPlugin from './plugins/PasteLogPlugin';
import {TableContext} from './plugins/TablePlugin';
import TestRecorderPlugin from './plugins/TestRecorderPlugin';
import TypingPerfPlugin from './plugins/TypingPerfPlugin';
import Settings from './Settings';
import PlaygroundEditorTheme from './themes/PlaygroundEditorTheme';
console.warn(
'If you are profiling the playground app, please ensure you turn off the debug view. You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.',
);
function prepopulatedRichText() {
const root = $getRoot();
if (root.getFirstChild() === null) {
const heading = $createHeadingNode('h1');
heading.append($createTextNode('Welcome to the playground'));
root.append(heading);
const quote = $createQuoteNode();
quote.append(
$createTextNode(
`In case you were wondering what the black box at the bottom is it's the debug view, showing the current state of the editor. ` +
`You can disable it by pressing on the settings control in the bottom-left of your screen and toggling the debug view setting.`,
),
);
root.append(quote);
const paragraph = $createParagraphNode();
paragraph.append(
$createTextNode('The playground is a demo environment built with '),
$createTextNode('@lexical/react').toggleFormat('code'),
$createTextNode('.'),
$createTextNode(' Try typing in '),
$createTextNode('some text').toggleFormat('bold'),
$createTextNode(' with '),
$createTextNode('different').toggleFormat('italic'),
$createTextNode(' formats.'),
);
root.append(paragraph);
const paragraph2 = $createParagraphNode();
paragraph2.append(
$createTextNode(
'Make sure to check out the various plugins in the toolbar. You can also use #hashtags or @-mentions too!',
),
);
root.append(paragraph2);
const paragraph3 = $createParagraphNode();
paragraph3.append(
$createTextNode(`If you'd like to find out more about Lexical, you can:`),
);
root.append(paragraph3);
const list = $createListNode('bullet');
list.append(
$createListItemNode().append(
$createTextNode(`Visit the `),
$createLinkNode('https://lexical.dev/').append(
$createTextNode('Lexical website'),
),
$createTextNode(` for documentation and more information.`),
),
$createListItemNode().append(
$createTextNode(`Check out the code on our `),
$createLinkNode('https://github.com/facebook/lexical').append(
$createTextNode('GitHub repository'),
),
$createTextNode(`.`),
),
$createListItemNode().append(
$createTextNode(`Playground code can be found `),
$createLinkNode(
'https://github.com/facebook/lexical/tree/main/packages/lexical-playground',
).append($createTextNode('here')),
$createTextNode(`.`),
),
$createListItemNode().append(
$createTextNode(`Join our `),
$createLinkNode('https://discord.com/invite/KmG4wQnnD9').append(
$createTextNode('Discord Server'),
),
$createTextNode(` and chat with the team.`),
),
);
root.append(list);
const paragraph4 = $createParagraphNode();
paragraph4.append(
$createTextNode(
`Lastly, we're constantly adding cool new features to this playground. So make sure you check back here when you next get a chance :).`,
),
);
root.append(paragraph4);
}
}
function LexicalApp(props: { noteId: bigint; editData: object | null; noteTitle: string; handleLawClick_item1: any; }): JSX.Element {
const {
settings: {isCollab, emptyEditor, measureTypingPerf},
} = useSettings();
console.log(props.noteId)
// console.log(props.editData)
console.log(props.editData!==null)
console.log(prepopulatedRichText)
const initialConfig = {
// editorState: isCollab
// ? null
// : emptyEditor
// ? undefined
// : prepopulatedRichText,
editorState: props.editData!==null?props.editData:prepopulatedRichText,
namespace: 'Playground',
nodes: [...PlaygroundNodes],
onError: (error: Error) => {
throw error;
},
theme: PlaygroundEditorTheme,
};
return (
<LexicalComposer initialConfig={initialConfig}>
<SharedHistoryContext>
<TableContext>
<SharedAutocompleteContext>
{/*<header>*/}
{/* <a href="https://lexical.dev" target="_blank" rel="noreferrer">*/}
{/* <img src={logo} alt="Lexical Logo" />*/}
{/* </a>*/}
{/*</header>*/}
<div className="editor-shell">
<Editor noteId={props.noteId} noteTitle={props.noteTitle} editData ={props.editData} handleLawClick_item2={props.handleLawClick_item1}/>
</div>
{/*<Settings />*/}
{/*{isDevPlayground ? <DocsPlugin /> : null}*/}
{/*{isDevPlayground ? <PasteLogPlugin /> : null}*/}
{/*{isDevPlayground ? <TestRecorderPlugin /> : null}*/}
{measureTypingPerf ? <TypingPerfPlugin /> : null}
</SharedAutocompleteContext>
</TableContext>
</SharedHistoryContext>
</LexicalComposer>
);
}
export default function PlaygroundApp(props: { noteId: bigint; noteTitle: string; editData: object; handleLawClick: any; }): JSX.Element {
return (
// <Editor />
<LexicalApp noteId={props.noteId} noteTitle={props.noteTitle} editData ={props.editData} handleLawClick_item1={props.handleLawClick}/>
//
// <SettingsContext>
// <LexicalApp />
// <a
// href="https://github.com/facebook/lexical/tree/main/packages/lexical-playground"
// className="github-corner"
// aria-label="View source on GitHub">
// <svg
// width="80"
// height="80"
// viewBox="0 0 250 250"
// style={{
// border: '0',
// color: '#eee',
// fill: '#222',
// left: '0',
// position: 'absolute',
// top: '0',
// transform: 'scale(-1,1)',
// }}
// aria-hidden="true">
// <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" />
// <path
// d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
// fill="currentColor"
// style={{
// transformOrigin: '130px 106px',
// }}
// className="octo-arm"
// />
// <path
// d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
// fill="currentColor"
// className="octo-body"
// />
// </svg>
// </a>
// </SettingsContext>
);
}
@@ -0,0 +1,150 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import * as React from 'react';
import {useMemo, useState} from 'react';
import {isDevPlayground} from './appSettings';
import {useSettings} from './context/SettingsContext';
import Switch from './ui/Switch';
export default function Settings(): JSX.Element {
const windowLocation = window.location;
const {
setOption,
settings: {
measureTypingPerf,
isCollab,
isRichText,
isMaxLength,
isCharLimit,
isCharLimitUtf8,
isAutocomplete,
showTreeView,
showNestedEditorTreeView,
disableBeforeInput,
showTableOfContents,
shouldUseLexicalContextMenu,
},
} = useSettings();
const [showSettings, setShowSettings] = useState(false);
const [isSplitScreen, search] = useMemo(() => {
const parentWindow = window.parent;
const _search = windowLocation.search;
const _isSplitScreen =
parentWindow && parentWindow.location.pathname === '/split/';
return [_isSplitScreen, _search];
}, [windowLocation]);
return (
<>
<button
id="options-button"
className={`editor-dev-button ${showSettings ? 'active' : ''}`}
onClick={() => setShowSettings(!showSettings)}
/>
{showSettings ? (
<div className="switches">
{isRichText && isDevPlayground && (
<Switch
onClick={() => {
setOption('isCollab', !isCollab);
window.location.reload();
}}
checked={isCollab}
text="Collaboration"
/>
)}
{isDevPlayground && (
<Switch
onClick={() => {
if (isSplitScreen) {
window.parent.location.href = `/${search}`;
} else {
window.location.href = `/split/${search}`;
}
}}
checked={isSplitScreen}
text="Split Screen"
/>
)}
<Switch
onClick={() => setOption('measureTypingPerf', !measureTypingPerf)}
checked={measureTypingPerf}
text="Measure Perf"
/>
<Switch
onClick={() => setOption('showTreeView', !showTreeView)}
checked={showTreeView}
text="Debug View"
/>
<Switch
onClick={() =>
setOption('showNestedEditorTreeView', !showNestedEditorTreeView)
}
checked={showNestedEditorTreeView}
text="Nested Editors Debug View"
/>
<Switch
onClick={() => {
setOption('isRichText', !isRichText);
setOption('isCollab', false);
}}
checked={isRichText}
text="Rich Text"
/>
<Switch
onClick={() => setOption('isCharLimit', !isCharLimit)}
checked={isCharLimit}
text="Char Limit"
/>
<Switch
onClick={() => setOption('isCharLimitUtf8', !isCharLimitUtf8)}
checked={isCharLimitUtf8}
text="Char Limit (UTF-8)"
/>
<Switch
onClick={() => setOption('isMaxLength', !isMaxLength)}
checked={isMaxLength}
text="Max Length"
/>
<Switch
onClick={() => setOption('isAutocomplete', !isAutocomplete)}
checked={isAutocomplete}
text="Autocomplete"
/>
<Switch
onClick={() => {
setOption('disableBeforeInput', !disableBeforeInput);
setTimeout(() => window.location.reload(), 500);
}}
checked={disableBeforeInput}
text="Legacy Events"
/>
<Switch
onClick={() => {
setOption('showTableOfContents', !showTableOfContents);
}}
checked={showTableOfContents}
text="Table Of Contents"
/>
<Switch
onClick={() => {
setOption(
'shouldUseLexicalContextMenu',
!shouldUseLexicalContextMenu,
);
}}
checked={shouldUseLexicalContextMenu}
text="Use Lexical Context Menu"
/>
</div>
) : null}
</>
);
}

Some files were not shown because too many files have changed in this diff Show More