Compare commits
No commits in common. "1f34d041b78a35b6758de7aa2e41ad2fe247ede8" and "92c30173cb018cd06ccd4c246f722d7c099a0b2d" have entirely different histories.
1f34d041b7
...
92c30173cb
26
build.gradle
@ -25,26 +25,22 @@ jar {
|
|||||||
enabled(false)
|
enabled(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
configurations.implementation {
|
|
||||||
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
implementation("org.springframework.boot:spring-boot-starter-web") {
|
||||||
implementation("org.springframework.boot:spring-boot-starter-security")
|
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
|
||||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
}
|
||||||
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
|
|
||||||
implementation("org.springframework.boot:spring-boot-starter-log4j2")
|
implementation("org.springframework.boot:spring-boot-starter-log4j2")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
|
|
||||||
|
|
||||||
implementation 'org.codehaus.groovy:groovy-all:3.0.8'
|
implementation 'org.codehaus.groovy:groovy-all:3.0.8'
|
||||||
|
|
||||||
|
|
||||||
implementation 'com.sedmelluq:lavaplayer:1.3.77'
|
implementation 'com.sedmelluq:lavaplayer:1.3.77'
|
||||||
implementation 'net.dv8tion:JDA:4.4.0_350'
|
implementation 'net.dv8tion:JDA:4.4.0_350'
|
||||||
implementation group: 'org.json', name: 'json', version: '20210307'
|
implementation group: 'org.json', name: 'json', version: '20210307'
|
||||||
|
implementation 'org.springframework.security:spring-security-web:5.5.0'
|
||||||
// JPA Data (We are going to use Repositories, Entities, Hibernate, etc...)
|
// JPA Data (We are going to use Repositories, Entities, Hibernate, etc...)
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-data-jpa") {
|
||||||
|
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
|
||||||
|
}
|
||||||
implementation(platform("org.apache.logging.log4j:log4j-bom:2.17.1"))
|
implementation(platform("org.apache.logging.log4j:log4j-bom:2.17.1"))
|
||||||
// Use MySQL Connector-J
|
// Use MySQL Connector-J
|
||||||
implementation 'mysql:mysql-connector-java'
|
implementation 'mysql:mysql-connector-java'
|
||||||
@ -52,10 +48,14 @@ dependencies {
|
|||||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||||
implementation 'com.google.api-client:google-api-client:1.31.5'
|
implementation 'com.google.api-client:google-api-client:1.31.5'
|
||||||
implementation 'com.google.apis:google-api-services-youtube:v3-rev20210410-1.31.0'
|
implementation 'com.google.apis:google-api-services-youtube:v3-rev20210410-1.31.0'
|
||||||
|
|
||||||
|
|
||||||
implementation group: 'org.jsoup', name: 'jsoup', version: '1.13.1'
|
implementation group: 'org.jsoup', name: 'jsoup', version: '1.13.1'
|
||||||
|
|
||||||
|
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-thymeleaf") {
|
||||||
|
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Version {
|
class Version {
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
package net.Broken.Api;
|
|
||||||
|
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
|
||||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
|
|
||||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/v2")
|
|
||||||
public class AuthController {
|
|
||||||
@GetMapping("user")
|
|
||||||
public String helloUser() {
|
|
||||||
return "Hello User";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("admin")
|
|
||||||
public String helloAdmin() {
|
|
||||||
return "Hello Admin";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package net.Broken.Api.Security;
|
|
||||||
|
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.core.AuthenticationException;
|
|
||||||
|
|
||||||
public class DiscordAuthenticationProvider implements AuthenticationProvider {
|
|
||||||
@Override
|
|
||||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
|
||||||
authentication.getCredentials()
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean supports(Class<?> authentication) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package net.Broken.Api.Security;
|
|
||||||
|
|
||||||
import net.Broken.DB.Entity.UserEntity;
|
|
||||||
import net.Broken.DB.Repository.UserRepository;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DiscordUserDetailsService implements UserDetailsService {
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
|
|
||||||
public DiscordUserDetailsService(UserRepository userRepository) {
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
|
||||||
List<UserEntity> user = userRepository.findByName(username);
|
|
||||||
if(user.isEmpty()){
|
|
||||||
throw new UsernameNotFoundException(username);
|
|
||||||
}
|
|
||||||
return new DiscordUserPrincipal(user.get(0));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
package net.Broken.Api.Security;
|
|
||||||
|
|
||||||
import net.Broken.DB.Entity.UserEntity;
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class DiscordUserPrincipal implements UserDetails {
|
|
||||||
private UserEntity user;
|
|
||||||
|
|
||||||
public DiscordUserPrincipal(UserEntity user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPassword() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsername() {
|
|
||||||
return user.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAccountNonExpired() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAccountNonLocked() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCredentialsNonExpired() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDiscordId(){
|
|
||||||
return user.getJdaId();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package net.Broken.Api.Security;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.RequestEntity;
|
|
||||||
|
|
||||||
class OAuth2UserAgentUtils {
|
|
||||||
static RequestEntity<?> withUserAgent(RequestEntity<?> request) {
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.putAll(request.getHeaders());
|
|
||||||
headers.add(HttpHeaders.USER_AGENT, DISCORD_BOT_USER_AGENT);
|
|
||||||
|
|
||||||
return new RequestEntity<>(request.getBody(), headers, request.getMethod(), request.getUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String DISCORD_BOT_USER_AGENT = "DiscordBot (https://github.com/fourscouts/blog/tree/master/oauth2-discord)";
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package net.Broken.Api.Security;
|
|
||||||
|
|
||||||
import net.Broken.DB.Repository.UserRepository;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
|
||||||
|
|
||||||
@EnableWebSecurity
|
|
||||||
@Configuration
|
|
||||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
|
|
||||||
public SecurityConfig(UserRepository userRepository) {
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
|
||||||
|
|
||||||
http.authorizeRequests()
|
|
||||||
// Our private endpoints
|
|
||||||
.anyRequest().authenticated();
|
|
||||||
|
|
||||||
// http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
|
|
||||||
// response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
|
||||||
// });
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
package net.Broken.Api.Services;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DiscordOauthService {
|
|
||||||
|
|
||||||
@Value("${discord.client-id}")
|
|
||||||
private String clientId;
|
|
||||||
|
|
||||||
@Value("${discord.client-secret}")
|
|
||||||
private String clientSecret;
|
|
||||||
|
|
||||||
@Value("${discord.token-endpoint}")
|
|
||||||
private String tokenEndpoint;
|
|
||||||
|
|
||||||
public String getAccessToken(String code, String redirectUrl){
|
|
||||||
HashMap<String, String> data = new HashMap<>();
|
|
||||||
data.put("client_id", this.clientId);
|
|
||||||
data.put("client_secret", this.clientSecret);
|
|
||||||
data.put("grant_type", "authorization_code");
|
|
||||||
data.put("code", code);
|
|
||||||
data.put("redirect_uri", redirectUrl);
|
|
||||||
|
|
||||||
Gson gson = new Gson();
|
|
||||||
HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString(gson.toJson(data));
|
|
||||||
|
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(tokenEndpoint))
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.POST(body)
|
|
||||||
.build();
|
|
||||||
HttpClient client = HttpClient.newHttpClient();
|
|
||||||
client.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package net.Broken.Api.Services;
|
|
||||||
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
|
|
||||||
public class DiscordUserDetailService implements UserDetailsService {
|
|
||||||
@Override
|
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
12
src/main/java/net/Broken/webView/CheckPage.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package net.Broken.webView;
|
||||||
|
|
||||||
|
import net.Broken.MainBot;
|
||||||
|
|
||||||
|
public class CheckPage {
|
||||||
|
public static String getPageIfReady(String page) {
|
||||||
|
if (MainBot.ready)
|
||||||
|
return page;
|
||||||
|
else
|
||||||
|
return "loading";
|
||||||
|
}
|
||||||
|
}
|
207
src/main/java/net/Broken/webView/GeneralWebView.java
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
package net.Broken.webView;
|
||||||
|
|
||||||
|
import net.Broken.DB.Entity.UserEntity;
|
||||||
|
import net.Broken.DB.Repository.UserRepository;
|
||||||
|
import net.Broken.MainBot;
|
||||||
|
import net.Broken.Tools.CacheTools;
|
||||||
|
import net.Broken.Tools.SettingsUtils;
|
||||||
|
import net.Broken.Tools.UserManager.Exceptions.UnknownTokenException;
|
||||||
|
import net.Broken.Tools.UserManager.Stats.GuildStatsPack;
|
||||||
|
import net.Broken.Tools.UserManager.Stats.UserStatsUtils;
|
||||||
|
import net.Broken.Tools.UserManager.UserUtils;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.CookieValue;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web page controller for index
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class GeneralWebView {
|
||||||
|
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
private UserUtils userUtils = UserUtils.getInstance();
|
||||||
|
|
||||||
|
private Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public GeneralWebView(UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Model addGuildAndRedirect(Model model, String token, String guildId, User user) {
|
||||||
|
List<Guild> mutualGuilds = user.getMutualGuilds();
|
||||||
|
Integer lastCount = MainBot.mutualGuildCount.get(user.getId());
|
||||||
|
if (lastCount == null || lastCount != mutualGuilds.size()) {
|
||||||
|
LogManager.getLogger().debug("Guild miss match, re-cache users...");
|
||||||
|
CacheTools.loadAllGuildMembers();
|
||||||
|
mutualGuilds = user.getMutualGuilds();
|
||||||
|
MainBot.mutualGuildCount.put(user.getId(), mutualGuilds.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
Guild guild = MainBot.jda.getGuildById(guildId);
|
||||||
|
if (guild != null) {
|
||||||
|
model.addAttribute("guild_name", guild.getName());
|
||||||
|
model.addAttribute("guild_id", guild.getId());
|
||||||
|
model.addAttribute("guild_icon", guild.getIconUrl() == null ? "https://discordapp.com/assets/dd4dbc0016779df1378e7812eabaa04d.png" : guild.getIconUrl());
|
||||||
|
model.addAttribute("mutual_guilds", mutualGuilds);
|
||||||
|
model.addAttribute("isAdmin", SettingsUtils.getInstance().checkPermission(token, guildId));
|
||||||
|
} else {
|
||||||
|
model.addAttribute("guild_name", "");
|
||||||
|
model.addAttribute("guild_icon", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/")
|
||||||
|
public String music(Model model, HttpServletResponse response, HttpServletRequest request, @CookieValue(value = "guild", defaultValue = "1") String guildId, @CookieValue(value = "token", defaultValue = "") String token) {
|
||||||
|
if (token.equals("")) {
|
||||||
|
model.addAttribute("isLogged", false);
|
||||||
|
model.addAttribute("guild_name", "");
|
||||||
|
model.addAttribute("isAdmin", false);
|
||||||
|
model.addAttribute("inviteLink", "https://discordapp.com/oauth2/authorize?client_id=" + MainBot.jda.getSelfUser().getId() + "&scope=bot&permissions=8");
|
||||||
|
|
||||||
|
return CheckPage.getPageIfReady("index");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
UserEntity userE = userUtils.getUserWithApiToken(userRepository, token);
|
||||||
|
User user = MainBot.jda.getUserById(userE.getJdaId());
|
||||||
|
if (user == null) {
|
||||||
|
model.addAttribute("noMutualGuilds", true);
|
||||||
|
addGuildAndRedirect(model, token, guildId, user);
|
||||||
|
} else {
|
||||||
|
model.addAttribute("noMutualGuilds", false);
|
||||||
|
addGuildAndRedirect(model, token, guildId, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addAttribute("isAdmin", SettingsUtils.getInstance().checkPermission(token, guildId));
|
||||||
|
model.addAttribute("isLogged", true);
|
||||||
|
model.addAttribute("inviteLink", "https://discordapp.com/oauth2/authorize?client_id=" + MainBot.jda.getSelfUser().getId() + "&scope=bot&permissions=8");
|
||||||
|
return CheckPage.getPageIfReady("index");
|
||||||
|
|
||||||
|
} catch (UnknownTokenException e) {
|
||||||
|
logger.debug("Unknown token, clear cookies");
|
||||||
|
Cookie[] cookies = request.getCookies();
|
||||||
|
logger.debug(cookies);
|
||||||
|
for (Cookie cookie : cookies) {
|
||||||
|
cookie.setMaxAge(0);
|
||||||
|
cookie.setValue(null);
|
||||||
|
cookie.setPath("/");
|
||||||
|
response.addCookie(cookie);
|
||||||
|
}
|
||||||
|
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
|
||||||
|
return CheckPage.getPageIfReady("login");
|
||||||
|
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
logger.debug("Unknown guild, flush cookies");
|
||||||
|
Cookie cookie = new Cookie("guild", null);
|
||||||
|
cookie.setPath("/");
|
||||||
|
cookie.setMaxAge(0);
|
||||||
|
response.addCookie(cookie);
|
||||||
|
return "redirect:/";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping("/loading")
|
||||||
|
public String loading(Model model) {
|
||||||
|
return "loading";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/forgetPass")
|
||||||
|
public String forgetPass(Model model) {
|
||||||
|
return CheckPage.getPageIfReady("forgetPass");
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/oauthCallback")
|
||||||
|
public String oauthCallback(Model model) {
|
||||||
|
return "oauthCallback";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/settings")
|
||||||
|
public String settings(Model model, @CookieValue(value = "guild", defaultValue = "") String guildId, @CookieValue(value = "token", defaultValue = "") String token) {
|
||||||
|
SettingsUtils settingsUtils = SettingsUtils.getInstance();
|
||||||
|
if (settingsUtils.checkPermission(token, guildId)) {
|
||||||
|
try {
|
||||||
|
UserEntity userE = userUtils.getUserWithApiToken(userRepository, token);
|
||||||
|
User user = MainBot.jda.getUserById(userE.getJdaId());
|
||||||
|
addGuildAndRedirect(model, token, guildId, user);
|
||||||
|
Guild guild = MainBot.jda.getGuildById(guildId);
|
||||||
|
model.addAttribute("settings", SettingsUtils.getInstance().extractSettings(guild));
|
||||||
|
} catch (UnknownTokenException e) {
|
||||||
|
throw new ForbiddenException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return CheckPage.getPageIfReady("settings");
|
||||||
|
} else
|
||||||
|
throw new ForbiddenException();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/login")
|
||||||
|
public String login(Model model, @CookieValue(value = "token", defaultValue = "") String token) {
|
||||||
|
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
|
||||||
|
if (!token.equals("")) {
|
||||||
|
return "redirect:/";
|
||||||
|
} else
|
||||||
|
return "login";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping("/rank")
|
||||||
|
public String login(Model model, @CookieValue(value = "token", defaultValue = "1") String token, @CookieValue(value = "guild", defaultValue = "") String cookieGuildId, @RequestParam(value = "guild", defaultValue = "") String praramGuildId) {
|
||||||
|
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
|
||||||
|
try {
|
||||||
|
UserEntity userEntity = userUtils.getUserWithApiToken(userRepository, token);
|
||||||
|
GuildStatsPack stack;
|
||||||
|
if (!cookieGuildId.equals("")) {
|
||||||
|
stack = UserStatsUtils.getINSTANCE().getStatPack(userEntity, cookieGuildId);
|
||||||
|
|
||||||
|
|
||||||
|
} else
|
||||||
|
stack = null;
|
||||||
|
model.addAttribute("stack", stack);
|
||||||
|
try {
|
||||||
|
UserEntity userE = userUtils.getUserWithApiToken(userRepository, token);
|
||||||
|
User user = CacheTools.getJdaUser(userE);
|
||||||
|
addGuildAndRedirect(model, token, cookieGuildId, user);
|
||||||
|
} catch (UnknownTokenException e) {
|
||||||
|
throw new ForbiddenException();
|
||||||
|
}
|
||||||
|
return CheckPage.getPageIfReady("rank");
|
||||||
|
|
||||||
|
} catch (UnknownTokenException e) {
|
||||||
|
return "login"; // TODO Public rank
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.FORBIDDEN)
|
||||||
|
public class ForbiddenException extends RuntimeException {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
78
src/main/java/net/Broken/webView/MusicWebView.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package net.Broken.webView;
|
||||||
|
|
||||||
|
import net.Broken.DB.Entity.UserEntity;
|
||||||
|
import net.Broken.DB.Repository.UserRepository;
|
||||||
|
import net.Broken.MainBot;
|
||||||
|
import net.Broken.Tools.UserManager.Exceptions.UnknownTokenException;
|
||||||
|
import net.Broken.Tools.UserManager.UserUtils;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.CookieValue;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web page controller for /music page
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class MusicWebView {
|
||||||
|
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
private UserUtils userUtils = UserUtils.getInstance();
|
||||||
|
|
||||||
|
private Logger logger = LogManager.getLogger();
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public MusicWebView(UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping("/music")
|
||||||
|
public String music(Model model, HttpServletResponse response, HttpServletRequest request, @CookieValue(value = "guild", defaultValue = "1") String guildId, @CookieValue(value = "token", defaultValue = "") String token) {
|
||||||
|
if (token.equals("")) {
|
||||||
|
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
|
||||||
|
return "login";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
UserEntity userE = userUtils.getUserWithApiToken(userRepository, token);
|
||||||
|
User user = MainBot.jda.getUserById(userE.getJdaId());
|
||||||
|
if (user == null)
|
||||||
|
return "redirect:/";
|
||||||
|
GeneralWebView.addGuildAndRedirect(model, token, guildId, user);
|
||||||
|
return CheckPage.getPageIfReady("music");
|
||||||
|
|
||||||
|
} catch (UnknownTokenException e) {
|
||||||
|
logger.debug("Unknown token, flush cookies");
|
||||||
|
Cookie[] cookies = request.getCookies();
|
||||||
|
for (Cookie cookie : cookies) {
|
||||||
|
cookie.setMaxAge(0);
|
||||||
|
cookie.setValue(null);
|
||||||
|
cookie.setPath("/");
|
||||||
|
response.addCookie(cookie);
|
||||||
|
}
|
||||||
|
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
|
||||||
|
return "login";
|
||||||
|
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
logger.debug("Unknown guild, flush cookies");
|
||||||
|
Cookie cookie = new Cookie("guild", null); // Not necessary, but saves bandwidth.
|
||||||
|
cookie.setPath("/");
|
||||||
|
cookie.setHttpOnly(true);
|
||||||
|
cookie.setMaxAge(0); // Don't set to -1 or it will become a session cookie!
|
||||||
|
response.addCookie(cookie);
|
||||||
|
return "redirect:music";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
37
src/main/java/net/Broken/webView/MvcApplication.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package net.Broken.webView;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
import org.springframework.web.servlet.resource.ContentVersionStrategy;
|
||||||
|
import org.springframework.web.servlet.resource.ResourceUrlEncodingFilter;
|
||||||
|
import org.springframework.web.servlet.resource.VersionResourceResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration for js auto versioning
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class MvcApplication implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
VersionResourceResolver versionResourceResolver = new VersionResourceResolver()
|
||||||
|
.addVersionStrategy(new ContentVersionStrategy(), "/**");
|
||||||
|
|
||||||
|
registry.addResourceHandler("/js/*.js")
|
||||||
|
.addResourceLocations("classpath:/static/js/")
|
||||||
|
.setCachePeriod(60 * 60 * 24 * 365) /* one year */
|
||||||
|
.resourceChain(true)
|
||||||
|
.addResolver(versionResourceResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
|
||||||
|
return new ResourceUrlEncodingFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
42
src/main/java/net/Broken/webView/MyErrorController.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package net.Broken.webView;
|
||||||
|
|
||||||
|
import net.Broken.MainBot;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import org.springframework.boot.web.servlet.error.ErrorController;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.CookieValue;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class MyErrorController implements ErrorController {
|
||||||
|
|
||||||
|
@RequestMapping("/error")
|
||||||
|
public String handleError(HttpServletRequest request, Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId) {
|
||||||
|
Guild guild = MainBot.jda.getGuildById(guildId);
|
||||||
|
if (guild != null)
|
||||||
|
model.addAttribute("guild_name", guild.getName());
|
||||||
|
else
|
||||||
|
model.addAttribute("guild_name", "");
|
||||||
|
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
|
||||||
|
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
|
||||||
|
if (status != null) {
|
||||||
|
Integer statusCode = Integer.valueOf(status.toString());
|
||||||
|
|
||||||
|
if (statusCode == HttpStatus.NOT_FOUND.value()) {
|
||||||
|
return "error/404";
|
||||||
|
} else if (statusCode == HttpStatus.FORBIDDEN.value()) {
|
||||||
|
return "error/403";
|
||||||
|
} else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
|
||||||
|
return "error/500";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return "error";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
src/main/java/net/Broken/webView/RegisterWebView.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package net.Broken.webView;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebPage Controller for /register
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class RegisterWebView {
|
||||||
|
@RequestMapping("/register")
|
||||||
|
public String music(@RequestParam(value = "id", required = true, defaultValue = "") String id, Model model) {
|
||||||
|
model.addAttribute("id", id);
|
||||||
|
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
|
||||||
|
model.addAttribute("isAdmin", false);
|
||||||
|
|
||||||
|
return CheckPage.getPageIfReady("register");
|
||||||
|
}
|
||||||
|
}
|
9
src/main/resources/application.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
server.port=${PORT}
|
||||||
|
spring.jpa.hibernate.ddl-auto=update
|
||||||
|
spring.datasource.url=${DB_URL}
|
||||||
|
spring.datasource.username=${DB_USER}
|
||||||
|
spring.datasource.password=${DB_PWD}
|
||||||
|
spring.thymeleaf.cache=true
|
||||||
|
server.compression.enabled=true
|
||||||
|
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
|
||||||
|
server.http2.enabled=true
|
@ -1,41 +0,0 @@
|
|||||||
spring:
|
|
||||||
datasource:
|
|
||||||
username: ${DB_USER}
|
|
||||||
url: ${DB_URL}
|
|
||||||
password: ${DB_PWD}
|
|
||||||
thymeleaf:
|
|
||||||
cache: 'true'
|
|
||||||
jpa:
|
|
||||||
hibernate:
|
|
||||||
ddl-auto: update
|
|
||||||
security:
|
|
||||||
oauth2:
|
|
||||||
client:
|
|
||||||
registration:
|
|
||||||
discord:
|
|
||||||
client-id: ${CLIENT_ID}
|
|
||||||
client-secret: ${CLIENT_SECRET}
|
|
||||||
clientAuthenticationMethod: post
|
|
||||||
authorizationGrantType: authorization_code
|
|
||||||
scope:
|
|
||||||
- identify
|
|
||||||
redirect-uri: "http://localhost:8080/login/oauth2/code/discord"
|
|
||||||
clientName: FourScouts client
|
|
||||||
provider:
|
|
||||||
discord:
|
|
||||||
authorizationUri: https://discordapp.com/api/oauth2/authorize
|
|
||||||
tokenUri: https://discordapp.com/api/oauth2/token
|
|
||||||
userInfoUri: https://discordapp.com/api/users/@me
|
|
||||||
userNameAttribute: username
|
|
||||||
server:
|
|
||||||
compression:
|
|
||||||
enabled: 'true'
|
|
||||||
mime-types: application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
|
|
||||||
port: ${PORT}
|
|
||||||
http2:
|
|
||||||
enabled: 'true'
|
|
||||||
|
|
||||||
discord:
|
|
||||||
client-id: ${CLIENT_ID}
|
|
||||||
client-secret: ${CLIENT_SECRET}
|
|
||||||
token-endpoint: https://discord.com/api/oauth2/token
|
|
@ -38,11 +38,6 @@
|
|||||||
<AppenderRef ref="current"/>
|
<AppenderRef ref="current"/>
|
||||||
<AppenderRef ref="RollingFile"/>
|
<AppenderRef ref="RollingFile"/>
|
||||||
</Logger>
|
</Logger>
|
||||||
<Logger name="org.springframework.security" level="${env:LOG_LEVEL}" additivity="false">
|
|
||||||
<AppenderRef ref="Console"/>
|
|
||||||
<AppenderRef ref="current"/>
|
|
||||||
<AppenderRef ref="RollingFile"/>
|
|
||||||
</Logger>
|
|
||||||
<Root level="debug">
|
<Root level="debug">
|
||||||
<AppenderRef ref="Console" level="info"/>
|
<AppenderRef ref="Console" level="info"/>
|
||||||
<AppenderRef ref="RollingFile" level="info"/>
|
<AppenderRef ref="RollingFile" level="info"/>
|
||||||
|
BIN
src/main/resources/static/css/font/norwester.ttf
Executable file
BIN
src/main/resources/static/css/font/norwester.woff
Executable file
299
src/main/resources/static/css/github-activity.css
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
/*!
|
||||||
|
* GitHub Activity Stream - v0.1.4 - 10/7/2015
|
||||||
|
* https://github.com/caseyscarborough/github-activity
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Casey Scarborough
|
||||||
|
* MIT License
|
||||||
|
* http://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
.gha-feed {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: Helvetica, arial, freesans, clean, sans-serif;
|
||||||
|
line-height: 1.3;
|
||||||
|
overflow-y: auto;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-feed, .gha-feed h2, .gha-feed h3, .gha-feed p, .gha-feed ul, .gha-feed li {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-feed ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-feed li {
|
||||||
|
list-style-type: none;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-feed small {
|
||||||
|
color: #666;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-feed small a {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-feed small a .more-commits {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.gha-time {
|
||||||
|
color: #bbb;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-feed a {
|
||||||
|
color: #4183c4;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-feed a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-feed pre {
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: 1px 1px 4px #bbb;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-header {
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
left: 1px;
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
padding: 10px;
|
||||||
|
height: 67px;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
background: #ffffff; /* Old browsers */
|
||||||
|
background: -moz-linear-gradient(top, #ffffff 0%, #f4f4f4 100%); /* FF3.6+ */
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #f4f4f4)); /* Chrome,Safari4+ */
|
||||||
|
background: -webkit-linear-gradient(top, #ffffff 0%, #f4f4f4 100%); /* Chrome10+,Safari5.1+ */
|
||||||
|
background: -o-linear-gradient(top, #ffffff 0%, #f4f4f4 100%); /* Opera 11.10+ */
|
||||||
|
background: -ms-linear-gradient(top, #ffffff 0%, #f4f4f4 100%); /* IE10+ */
|
||||||
|
background: linear-gradient(to bottom, #ffffff 0%, #f4f4f4 100%); /* W3C */
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f4f4f4', GradientType=0); /* IE6-9 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -1px;
|
||||||
|
left: 1px;
|
||||||
|
padding: 5px;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
height: 16px;
|
||||||
|
width: calc(100% - 15px);
|
||||||
|
background: #ffffff; /* Old browsers */
|
||||||
|
background: -moz-linear-gradient(top, #ffffff 0%, #f4f4f4 100%); /* FF3.6+ */
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #f4f4f4)); /* Chrome,Safari4+ */
|
||||||
|
background: -webkit-linear-gradient(top, #ffffff 0%, #f4f4f4 100%); /* Chrome10+,Safari5.1+ */
|
||||||
|
background: -o-linear-gradient(top, #ffffff 0%, #f4f4f4 100%); /* Opera 11.10+ */
|
||||||
|
background: -ms-linear-gradient(top, #ffffff 0%, #f4f4f4 100%); /* IE10+ */
|
||||||
|
background: linear-gradient(to bottom, #ffffff 0%, #f4f4f4 100%); /* W3C */
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f4f4f4', GradientType=0); /* IE6-9 */
|
||||||
|
color: #495961;
|
||||||
|
font-size: 13px;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-footer a {
|
||||||
|
float: right;
|
||||||
|
color: #495961;
|
||||||
|
padding-right: 20px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-footer a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-header a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-github-icon {
|
||||||
|
display: inline;
|
||||||
|
float: left;
|
||||||
|
padding: 9px 0 0;
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
color: #495961;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-github-icon .octicon {
|
||||||
|
font: normal normal 40px octicons;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-gravatar {
|
||||||
|
display: inline;
|
||||||
|
float: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
padding-right: 20px;
|
||||||
|
max-width: 60px;
|
||||||
|
height: 67px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-gravatar img {
|
||||||
|
padding: 3px;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
box-shadow: 1px 1px 3px #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-activity {
|
||||||
|
clear: both;
|
||||||
|
padding: 10px 0;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.gha-activity.gha-small {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-activity.gha-small a {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-activity.gha-small span {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-activity:last-child {
|
||||||
|
padding-bottom: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-repo {
|
||||||
|
clear: both;
|
||||||
|
padding: 10px 0;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-activity-icon .octicon {
|
||||||
|
display: inline;
|
||||||
|
float: left;
|
||||||
|
clear: both;
|
||||||
|
margin: 6px auto;
|
||||||
|
width: 50px;
|
||||||
|
color: #bbb;
|
||||||
|
text-align: center;
|
||||||
|
font: normal normal 30px octicons;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-activity-icon .gha-small {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-message {
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-message-commits {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-message-merge {
|
||||||
|
padding: 3px 7px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: #e8f1f6;
|
||||||
|
color: rgba(0, 0, 0, 0.5);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-sha {
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-gravatar-small {
|
||||||
|
float: left;
|
||||||
|
margin-right: 6px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-gravatar-commit {
|
||||||
|
margin-bottom: -3px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-gravatar-user {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-user-info {
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 6px 10px 5px;
|
||||||
|
color: #495961;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-user-info a {
|
||||||
|
color: #495961;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-user-info p a {
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-without-name {
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-info {
|
||||||
|
margin: 15px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #e4e4c6;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #ffffde;
|
||||||
|
color: #6d6d4b;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-time {
|
||||||
|
color: #bbb;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-muted {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-push {
|
||||||
|
height: 87px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gha-push-small {
|
||||||
|
height: 26px;
|
||||||
|
}
|
9261
src/main/resources/static/css/materialize.css
vendored
Normal file
13
src/main/resources/static/css/materialize.min.css
vendored
Normal file
43
src/main/resources/static/css/style.css
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*.nav-wrapper{*/
|
||||||
|
/*!*margin-right: 1%;*!*/
|
||||||
|
/*margin-left: 1%;*/
|
||||||
|
/*width: 100%;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
|
||||||
|
.collapsible-body {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
min-height: 100vh;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Norwester";
|
||||||
|
src: url("/css/font/norwester.ttf"),
|
||||||
|
url("/css/font/norwester.woff");
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-logo {
|
||||||
|
font-family: Norwester;
|
||||||
|
font-size: 45px !important;
|
||||||
|
font-weight: bold;
|
||||||
|
-webkit-text-fill-color: #fbcf40;
|
||||||
|
-webkit-text-stroke-color: black;
|
||||||
|
-webkit-text-stroke-width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dropdown_guilds a:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dropdown_guilds li:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.2) !important;
|
||||||
|
}
|
BIN
src/main/resources/static/favicon.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
src/main/resources/static/fonts/roboto/Roboto-Bold.woff
Normal file
BIN
src/main/resources/static/fonts/roboto/Roboto-Bold.woff2
Normal file
BIN
src/main/resources/static/fonts/roboto/Roboto-Light.woff
Normal file
BIN
src/main/resources/static/fonts/roboto/Roboto-Light.woff2
Normal file
BIN
src/main/resources/static/fonts/roboto/Roboto-Medium.woff
Normal file
BIN
src/main/resources/static/fonts/roboto/Roboto-Medium.woff2
Normal file
BIN
src/main/resources/static/fonts/roboto/Roboto-Regular.woff
Normal file
BIN
src/main/resources/static/fonts/roboto/Roboto-Regular.woff2
Normal file
BIN
src/main/resources/static/fonts/roboto/Roboto-Thin.woff
Normal file
BIN
src/main/resources/static/fonts/roboto/Roboto-Thin.woff2
Normal file
1
src/main/resources/static/googlefa6384608522214e.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
google-site-verification: googlefa6384608522214e.html
|
6
src/main/resources/static/img/.directory
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[Dolphin]
|
||||||
|
Timestamp=2017,12,24,15,16,6
|
||||||
|
Version=4
|
||||||
|
|
||||||
|
[Settings]
|
||||||
|
HiddenFilesShown=true
|
BIN
src/main/resources/static/img/403.gif
Normal file
After Width: | Height: | Size: 7.6 MiB |
BIN
src/main/resources/static/img/404.gif
Normal file
After Width: | Height: | Size: 4.9 MiB |
BIN
src/main/resources/static/img/500.gif
Normal file
After Width: | Height: | Size: 7.2 MiB |
BIN
src/main/resources/static/img/GitHub.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
src/main/resources/static/img/GitHub_Logo.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
src/main/resources/static/img/disconnected.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
src/main/resources/static/img/icon_192.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
src/main/resources/static/img/icon_512.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
src/main/resources/static/img/no_music.jpg
Normal file
After Width: | Height: | Size: 125 KiB |
3678
src/main/resources/static/js/fontawesome.js
Normal file
560
src/main/resources/static/js/github-activity.js
Normal file
@ -0,0 +1,560 @@
|
|||||||
|
/*!
|
||||||
|
* GitHub Activity Stream - v0.1.4 - 10/7/2015
|
||||||
|
* https://github.com/caseyscarborough/github-activity
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Casey Scarborough
|
||||||
|
* MIT License
|
||||||
|
* http://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
var GitHubActivity = (function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var obj = {};
|
||||||
|
|
||||||
|
var methods = {
|
||||||
|
renderLink: function (url, title, cssClass) {
|
||||||
|
if (!title) {
|
||||||
|
title = url;
|
||||||
|
}
|
||||||
|
if (typeof (cssClass) === 'undefined') cssClass = "";
|
||||||
|
return Mustache.render('<a class="' + cssClass + '" href="{{url}}" target="_blank">{{{title}}}</a>', {
|
||||||
|
url: url,
|
||||||
|
title: title
|
||||||
|
});
|
||||||
|
},
|
||||||
|
renderGitHubLink: function (url, title, cssClass) {
|
||||||
|
if (!title) {
|
||||||
|
title = url;
|
||||||
|
}
|
||||||
|
if (typeof (cssClass) === 'undefined') cssClass = "";
|
||||||
|
return methods.renderLink('https://github.com/' + url, title, cssClass);
|
||||||
|
},
|
||||||
|
getMessageFor: function (data) {
|
||||||
|
var p = data.payload;
|
||||||
|
data.repoLink = methods.renderGitHubLink(data.repo.name);
|
||||||
|
data.userGravatar = Mustache.render('<div class="gha-gravatar-user"><img src="{{url}}" class="gha-gravatar-small"></div>', {url: data.actor.avatar_url});
|
||||||
|
|
||||||
|
// Get the branch name if it exists.
|
||||||
|
if (p.ref) {
|
||||||
|
if (p.ref.substring(0, 11) === 'refs/heads/') {
|
||||||
|
data.branch = p.ref.substring(11);
|
||||||
|
} else {
|
||||||
|
data.branch = p.ref;
|
||||||
|
}
|
||||||
|
data.branchLink = methods.renderGitHubLink(data.repo.name + '/tree/' + data.branch, data.branch) + ' at ';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only show the first 6 characters of the SHA of each commit if given.
|
||||||
|
if (p.commits) {
|
||||||
|
var shaDiff = p.before + '...' + p.head;
|
||||||
|
var length = p.commits.length;
|
||||||
|
if (length === 2) {
|
||||||
|
// If there are 2 commits, show message 'View comparison for these 2 commits >>'
|
||||||
|
data.commitsMessage = Mustache.render('<a href="https://github.com/{{repo}}/compare/{{shaDiff}}">View comparison for these 2 commits »</a>', {
|
||||||
|
repo: data.repo.name,
|
||||||
|
shaDiff: shaDiff
|
||||||
|
});
|
||||||
|
} else if (length > 2) {
|
||||||
|
// If there are more than two, show message '(numberOfCommits - 2) more commits >>'
|
||||||
|
data.commitsMessage = Mustache.render('<a href="https://github.com/{{repo}}/compare/{{shaDiff}}">{{length}} more ' + pluralize('commit', length - 2) + ' »</a>', {
|
||||||
|
repo: data.repo.name,
|
||||||
|
shaDiff: shaDiff,
|
||||||
|
length: p.size - 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
p.commits.forEach(function (d, i) {
|
||||||
|
if (d.message.length > 66) {
|
||||||
|
d.message = d.message.substring(0, 66) + '...';
|
||||||
|
}
|
||||||
|
if (i < 2) {
|
||||||
|
d.shaLink = methods.renderGitHubLink(data.repo.name + '/commit/' + d.sha, d.sha.substring(0, 6), 'gha-sha');
|
||||||
|
d.committerGravatar = Mustache.render('<img class="gha-gravatar-commit" src="https://gravatar.com/avatar/{{hash}}?s=30&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png" width="16" />', {hash: md5(d.author.email)});
|
||||||
|
} else {
|
||||||
|
// Delete the rest of the commits after the first 2, and then break out of the each loop.
|
||||||
|
p.commits.splice(2, p.size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the link if this is an IssueEvent.
|
||||||
|
if (p.issue) {
|
||||||
|
var title = data.repo.name + "#" + p.issue.number;
|
||||||
|
data.issueLink = methods.renderLink(p.issue.html_url, title);
|
||||||
|
data.issueType = "issue";
|
||||||
|
if (p.issue.pull_request) {
|
||||||
|
data.issueType = "pull request";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the pull request link if this is a PullRequestEvent.
|
||||||
|
if (p.pull_request) {
|
||||||
|
var pr = p.pull_request;
|
||||||
|
data.pullRequestLink = methods.renderLink(pr.html_url, data.repo.name + "#" + pr.number);
|
||||||
|
data.mergeMessage = "";
|
||||||
|
|
||||||
|
// If this was a merge, set the merge message.
|
||||||
|
if (p.pull_request.merged) {
|
||||||
|
p.action = "merged";
|
||||||
|
var message = '{{c}} ' + pluralize('commit', pr.commits) + ' with {{a}} ' + pluralize('addition', pr.additions) + ' and {{d}} ' + pluralize('deletion', pr.deletions);
|
||||||
|
data.mergeMessage = Mustache.render('<br><small class="gha-message-merge">' + message + '</small>', {
|
||||||
|
c: pr.commits,
|
||||||
|
a: pr.additions,
|
||||||
|
d: pr.deletions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the link if this is a PullRequestReviewCommentEvent
|
||||||
|
if (p.comment && p.comment.pull_request_url) {
|
||||||
|
var title = data.repo.name + "#" + p.comment.pull_request_url.split('/').pop();
|
||||||
|
data.pullRequestLink = methods.renderLink(p.comment.html_url, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the comment if one exists, and trim it to 150 characters.
|
||||||
|
if (p.comment && p.comment.body) {
|
||||||
|
data.comment = p.comment.body;
|
||||||
|
if (data.comment.length > 150) {
|
||||||
|
data.comment = data.comment.substring(0, 150) + '...';
|
||||||
|
}
|
||||||
|
if (p.comment.html_url && p.comment.commit_id) {
|
||||||
|
var title = data.repo.name + '@' + p.comment.commit_id.substring(0, 10);
|
||||||
|
data.commentLink = methods.renderLink(p.comment.html_url, title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === 'ReleaseEvent') {
|
||||||
|
data.tagLink = methods.renderLink(p.release.html_url, p.release.tag_name);
|
||||||
|
data.zipLink = methods.renderLink(p.release.zipball_url, 'Download Source Code (zip)');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wiki event
|
||||||
|
if (data.type === 'GollumEvent') {
|
||||||
|
var page = p.pages[0];
|
||||||
|
data.actionType = page.action;
|
||||||
|
data.message = data.actionType.charAt(0).toUpperCase() + data.actionType.slice(1) + ' ';
|
||||||
|
data.message += methods.renderGitHubLink(page.html_url, page.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === 'FollowEvent') data.targetLink = methods.renderGitHubLink(p.target.login);
|
||||||
|
if (data.type === 'ForkEvent') data.forkLink = methods.renderGitHubLink(p.forkee.full_name);
|
||||||
|
if (data.type === 'MemberEvent') data.memberLink = methods.renderGitHubLink(p.member.login);
|
||||||
|
|
||||||
|
if (p.gist) {
|
||||||
|
data.actionType = p.action === 'fork' ? p.action + 'ed' : p.action + 'd';
|
||||||
|
data.gistLink = methods.renderLink(p.gist.html_url, 'gist: ' + p.gist.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
var message = Mustache.render(templates[data.type], data);
|
||||||
|
var timeString = millisecondsToStr(new Date() - new Date(data.created_at));
|
||||||
|
var icon;
|
||||||
|
|
||||||
|
if (data.type == 'CreateEvent' && (['repository', 'branch', 'tag'].indexOf(p.ref_type) >= 0)) {
|
||||||
|
// Display separate icons depending on type of create event.
|
||||||
|
icon = icons[data.type + '_' + p.ref_type];
|
||||||
|
} else {
|
||||||
|
icon = icons[data.type]
|
||||||
|
}
|
||||||
|
var activity = {
|
||||||
|
message: message,
|
||||||
|
icon: icon,
|
||||||
|
timeString: timeString,
|
||||||
|
userLink: methods.renderGitHubLink(data.actor.login)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (singleLineActivities.indexOf(data.type) > -1) {
|
||||||
|
return Mustache.render(templates.SingleLineActivity, activity);
|
||||||
|
}
|
||||||
|
return Mustache.render(templates.Activity, activity);
|
||||||
|
},
|
||||||
|
getHeaderHTML: function (data) {
|
||||||
|
if (data.name) {
|
||||||
|
data.userNameLink = methods.renderLink(data.html_url, data.name);
|
||||||
|
} else {
|
||||||
|
data.withoutName = ' without-name';
|
||||||
|
}
|
||||||
|
data.userLink = methods.renderLink(data.html_url, data.login);
|
||||||
|
data.gravatarLink = methods.renderLink(data.html_url, '<img src="' + data.avatar_url + '">');
|
||||||
|
|
||||||
|
return Mustache.render(templates.UserHeader, data);
|
||||||
|
},
|
||||||
|
getActivityHTML: function (data, limit) {
|
||||||
|
var text = '';
|
||||||
|
var dataLength = data.length;
|
||||||
|
if (limit && limit > dataLength) {
|
||||||
|
limit = dataLength;
|
||||||
|
}
|
||||||
|
limit = limit ? limit : dataLength;
|
||||||
|
|
||||||
|
if (limit === 0) {
|
||||||
|
return Mustache.render(templates.NoActivity, {});
|
||||||
|
}
|
||||||
|
for (var i = 0; i < limit; i++) {
|
||||||
|
text += methods.getMessageFor(data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
},
|
||||||
|
getOutputFromRequest: function (url, callback) {
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
request.open('GET', url);
|
||||||
|
request.setRequestHeader('Accept', 'application/vnd.github.v3+json');
|
||||||
|
|
||||||
|
request.onreadystatechange = function () {
|
||||||
|
if (request.readyState === 4) {
|
||||||
|
if (request.status >= 200 && request.status < 300) {
|
||||||
|
var data = JSON.parse(request.responseText);
|
||||||
|
callback(undefined, data);
|
||||||
|
} else {
|
||||||
|
callback('request for ' + url + ' yielded status ' + request.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
request.onerror = function () {
|
||||||
|
callback('An error occurred connecting to ' + url);
|
||||||
|
};
|
||||||
|
request.send();
|
||||||
|
},
|
||||||
|
renderStream: function (output, div) {
|
||||||
|
div.innerHTML = Mustache.render(templates.Stream, {text: output, footer: templates.Footer});
|
||||||
|
div.style.position = 'relative';
|
||||||
|
},
|
||||||
|
writeOutput: function (selector, content) {
|
||||||
|
var div = selector.charAt(0) === '#' ? document.getElementById(selector.substring(1)) : document.getElementsByClassName(selector.substring(1));
|
||||||
|
if (div instanceof HTMLCollection) {
|
||||||
|
for (var i = 0; i < div.length; i++) {
|
||||||
|
methods.renderStream(content, div[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
methods.renderStream(content, div);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
renderIfReady: function (selector, header, activity) {
|
||||||
|
if (header && activity) {
|
||||||
|
methods.writeOutput(selector, header + activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.feed = function (options) {
|
||||||
|
if (!options.username || !options.selector) {
|
||||||
|
throw "You must specify the username and selector options for the activity stream.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selector = options.selector,
|
||||||
|
userUrl = 'https://api.github.com/users/' + options.username,
|
||||||
|
eventsUrl = userUrl + '/events',
|
||||||
|
header,
|
||||||
|
activity;
|
||||||
|
|
||||||
|
if (!!options.repository) {
|
||||||
|
eventsUrl = 'https://api.github.com/repos/' + options.username + '/' + options.repository + '/events';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.clientId && options.clientSecret) {
|
||||||
|
var authString = '?client_id=' + options.clientId + '&client_secret=' + options.clientSecret;
|
||||||
|
userUrl += authString;
|
||||||
|
eventsUrl += authString;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!options.eventsUrl) {
|
||||||
|
eventsUrl = options.eventsUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow templates override
|
||||||
|
if (typeof options.templates == 'object') {
|
||||||
|
for (var template in templates) {
|
||||||
|
if (typeof options.templates[template] == 'string') {
|
||||||
|
templates[template] = options.templates[template];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
methods.getOutputFromRequest(userUrl, function (error, output) {
|
||||||
|
if (error) {
|
||||||
|
header = Mustache.render(templates.UserNotFound, {username: options.username});
|
||||||
|
} else {
|
||||||
|
header = methods.getHeaderHTML(output)
|
||||||
|
}
|
||||||
|
methods.renderIfReady(selector, header, activity)
|
||||||
|
});
|
||||||
|
|
||||||
|
methods.getOutputFromRequest(eventsUrl, function (error, output) {
|
||||||
|
if (error) {
|
||||||
|
activity = Mustache.render(templates.EventsNotFound, {username: options.username});
|
||||||
|
} else {
|
||||||
|
var limit = options.limit != 'undefined' ? parseInt(options.limit, 10) : null;
|
||||||
|
activity = methods.getActivityHTML(output, limit);
|
||||||
|
}
|
||||||
|
methods.renderIfReady(selector, header, activity);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}());
|
||||||
|
|
||||||
|
// Takes in milliseconds and converts it to a human readable time,
|
||||||
|
// such as 'about 3 hours ago' or '23 days ago'
|
||||||
|
function millisecondsToStr(milliseconds) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function numberEnding(number) {
|
||||||
|
return (number > 1) ? 's ago' : ' ago';
|
||||||
|
}
|
||||||
|
|
||||||
|
var temp = Math.floor(milliseconds / 1000);
|
||||||
|
|
||||||
|
var years = Math.floor(temp / 31536000);
|
||||||
|
if (years) return years + ' year' + numberEnding(years);
|
||||||
|
|
||||||
|
var months = Math.floor((temp %= 31536000) / 2592000);
|
||||||
|
if (months) return months + ' month' + numberEnding(months);
|
||||||
|
|
||||||
|
var days = Math.floor((temp %= 2592000) / 86400);
|
||||||
|
if (days) return days + ' day' + numberEnding(days);
|
||||||
|
|
||||||
|
var hours = Math.floor((temp %= 86400) / 3600);
|
||||||
|
if (hours) return 'about ' + hours + ' hour' + numberEnding(hours);
|
||||||
|
|
||||||
|
var minutes = Math.floor((temp %= 3600) / 60);
|
||||||
|
if (minutes) return minutes + ' minute' + numberEnding(minutes);
|
||||||
|
|
||||||
|
var seconds = temp % 60;
|
||||||
|
if (seconds) return seconds + ' second' + numberEnding(seconds);
|
||||||
|
|
||||||
|
return 'just now';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pluralizes a word, but only works when the word requires
|
||||||
|
// an 's' to be added for pluralization.
|
||||||
|
function pluralize(word, number) {
|
||||||
|
// Yeah I know, this sucks.
|
||||||
|
if (number !== 1) return word + 's';
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** MD5 methods written by Joseph Myers. http://www.myersdaily.org/joseph/javascript/md5-text.html */
|
||||||
|
function md5cycle(f, h) {
|
||||||
|
var g = f[0], e = f[1], j = f[2], i = f[3];
|
||||||
|
g = ff(g, e, j, i, h[0], 7, -680876936);
|
||||||
|
i = ff(i, g, e, j, h[1], 12, -389564586);
|
||||||
|
j = ff(j, i, g, e, h[2], 17, 606105819);
|
||||||
|
e = ff(e, j, i, g, h[3], 22, -1044525330);
|
||||||
|
g = ff(g, e, j, i, h[4], 7, -176418897);
|
||||||
|
i = ff(i, g, e, j, h[5], 12, 1200080426);
|
||||||
|
j = ff(j, i, g, e, h[6], 17, -1473231341);
|
||||||
|
e = ff(e, j, i, g, h[7], 22, -45705983);
|
||||||
|
g = ff(g, e, j, i, h[8], 7, 1770035416);
|
||||||
|
i = ff(i, g, e, j, h[9], 12, -1958414417);
|
||||||
|
j = ff(j, i, g, e, h[10], 17, -42063);
|
||||||
|
e = ff(e, j, i, g, h[11], 22, -1990404162);
|
||||||
|
g = ff(g, e, j, i, h[12], 7, 1804603682);
|
||||||
|
i = ff(i, g, e, j, h[13], 12, -40341101);
|
||||||
|
j = ff(j, i, g, e, h[14], 17, -1502002290);
|
||||||
|
e = ff(e, j, i, g, h[15], 22, 1236535329);
|
||||||
|
g = gg(g, e, j, i, h[1], 5, -165796510);
|
||||||
|
i = gg(i, g, e, j, h[6], 9, -1069501632);
|
||||||
|
j = gg(j, i, g, e, h[11], 14, 643717713);
|
||||||
|
e = gg(e, j, i, g, h[0], 20, -373897302);
|
||||||
|
g = gg(g, e, j, i, h[5], 5, -701558691);
|
||||||
|
i = gg(i, g, e, j, h[10], 9, 38016083);
|
||||||
|
j = gg(j, i, g, e, h[15], 14, -660478335);
|
||||||
|
e = gg(e, j, i, g, h[4], 20, -405537848);
|
||||||
|
g = gg(g, e, j, i, h[9], 5, 568446438);
|
||||||
|
i = gg(i, g, e, j, h[14], 9, -1019803690);
|
||||||
|
j = gg(j, i, g, e, h[3], 14, -187363961);
|
||||||
|
e = gg(e, j, i, g, h[8], 20, 1163531501);
|
||||||
|
g = gg(g, e, j, i, h[13], 5, -1444681467);
|
||||||
|
i = gg(i, g, e, j, h[2], 9, -51403784);
|
||||||
|
j = gg(j, i, g, e, h[7], 14, 1735328473);
|
||||||
|
e = gg(e, j, i, g, h[12], 20, -1926607734);
|
||||||
|
g = hh(g, e, j, i, h[5], 4, -378558);
|
||||||
|
i = hh(i, g, e, j, h[8], 11, -2022574463);
|
||||||
|
j = hh(j, i, g, e, h[11], 16, 1839030562);
|
||||||
|
e = hh(e, j, i, g, h[14], 23, -35309556);
|
||||||
|
g = hh(g, e, j, i, h[1], 4, -1530992060);
|
||||||
|
i = hh(i, g, e, j, h[4], 11, 1272893353);
|
||||||
|
j = hh(j, i, g, e, h[7], 16, -155497632);
|
||||||
|
e = hh(e, j, i, g, h[10], 23, -1094730640);
|
||||||
|
g = hh(g, e, j, i, h[13], 4, 681279174);
|
||||||
|
i = hh(i, g, e, j, h[0], 11, -358537222);
|
||||||
|
j = hh(j, i, g, e, h[3], 16, -722521979);
|
||||||
|
e = hh(e, j, i, g, h[6], 23, 76029189);
|
||||||
|
g = hh(g, e, j, i, h[9], 4, -640364487);
|
||||||
|
i = hh(i, g, e, j, h[12], 11, -421815835);
|
||||||
|
j = hh(j, i, g, e, h[15], 16, 530742520);
|
||||||
|
e = hh(e, j, i, g, h[2], 23, -995338651);
|
||||||
|
g = ii(g, e, j, i, h[0], 6, -198630844);
|
||||||
|
i = ii(i, g, e, j, h[7], 10, 1126891415);
|
||||||
|
j = ii(j, i, g, e, h[14], 15, -1416354905);
|
||||||
|
e = ii(e, j, i, g, h[5], 21, -57434055);
|
||||||
|
g = ii(g, e, j, i, h[12], 6, 1700485571);
|
||||||
|
i = ii(i, g, e, j, h[3], 10, -1894986606);
|
||||||
|
j = ii(j, i, g, e, h[10], 15, -1051523);
|
||||||
|
e = ii(e, j, i, g, h[1], 21, -2054922799);
|
||||||
|
g = ii(g, e, j, i, h[8], 6, 1873313359);
|
||||||
|
i = ii(i, g, e, j, h[15], 10, -30611744);
|
||||||
|
j = ii(j, i, g, e, h[6], 15, -1560198380);
|
||||||
|
e = ii(e, j, i, g, h[13], 21, 1309151649);
|
||||||
|
g = ii(g, e, j, i, h[4], 6, -145523070);
|
||||||
|
i = ii(i, g, e, j, h[11], 10, -1120210379);
|
||||||
|
j = ii(j, i, g, e, h[2], 15, 718787259);
|
||||||
|
e = ii(e, j, i, g, h[9], 21, -343485551);
|
||||||
|
f[0] = add32(g, f[0]);
|
||||||
|
f[1] = add32(e, f[1]);
|
||||||
|
f[2] = add32(j, f[2]);
|
||||||
|
f[3] = add32(i, f[3])
|
||||||
|
}
|
||||||
|
|
||||||
|
function cmn(h, e, d, c, g, f) {
|
||||||
|
e = add32(add32(e, h), add32(c, f));
|
||||||
|
return add32((e << g) | (e >>> (32 - g)), d)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ff(g, f, k, j, e, i, h) {
|
||||||
|
return cmn((f & k) | ((~f) & j), g, f, e, i, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
function gg(g, f, k, j, e, i, h) {
|
||||||
|
return cmn((f & j) | (k & (~j)), g, f, e, i, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
function hh(g, f, k, j, e, i, h) {
|
||||||
|
return cmn(f ^ k ^ j, g, f, e, i, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ii(g, f, k, j, e, i, h) {
|
||||||
|
return cmn(k ^ (f | (~j)), g, f, e, i, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
function md51(c) {
|
||||||
|
txt = "";
|
||||||
|
var e = c.length, d = [1732584193, -271733879, -1732584194, 271733878], b;
|
||||||
|
for (b = 64; b <= c.length; b += 64) {
|
||||||
|
md5cycle(d, md5blk(c.substring(b - 64, b)))
|
||||||
|
}
|
||||||
|
c = c.substring(b - 64);
|
||||||
|
var a = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
for (b = 0; b < c.length; b++) {
|
||||||
|
a[b >> 2] |= c.charCodeAt(b) << ((b % 4) << 3)
|
||||||
|
}
|
||||||
|
a[b >> 2] |= 128 << ((b % 4) << 3);
|
||||||
|
if (b > 55) {
|
||||||
|
md5cycle(d, a);
|
||||||
|
for (b = 0; b < 16; b++) {
|
||||||
|
a[b] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a[14] = e * 8;
|
||||||
|
md5cycle(d, a);
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
function md5blk(b) {
|
||||||
|
var c = [], a;
|
||||||
|
for (a = 0; a < 64; a += 4) {
|
||||||
|
c[a >> 2] = b.charCodeAt(a) + (b.charCodeAt(a + 1) << 8) + (b.charCodeAt(a + 2) << 16) + (b.charCodeAt(a + 3) << 24)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
var hex_chr = "0123456789abcdef".split("");
|
||||||
|
|
||||||
|
function rhex(c) {
|
||||||
|
var b = "", a = 0;
|
||||||
|
for (; a < 4; a++) {
|
||||||
|
b += hex_chr[(c >> (a * 8 + 4)) & 15] + hex_chr[(c >> (a * 8)) & 15]
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
function hex(a) {
|
||||||
|
for (var b = 0; b < a.length; b++) {
|
||||||
|
a[b] = rhex(a[b])
|
||||||
|
}
|
||||||
|
return a.join("")
|
||||||
|
}
|
||||||
|
|
||||||
|
function md5(a) {
|
||||||
|
return hex(md51(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
function add32(d, c) {
|
||||||
|
return (d + c) & 4294967295
|
||||||
|
}
|
||||||
|
|
||||||
|
if (md5("hello") != "5d41402abc4b2a76b9719d911017c592") {
|
||||||
|
function add32(a, d) {
|
||||||
|
var c = (a & 65535) + (d & 65535), b = (a >> 16) + (d >> 16) + (c >> 16);
|
||||||
|
return (b << 16) | (c & 65535)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
var templates = {
|
||||||
|
Stream: '<div class="gha-feed">{{{text}}}<div class="gha-push-small"></div>{{{footer}}}</div>',
|
||||||
|
Activity: '<div id="{{id}}" class="gha-activity">\
|
||||||
|
<div class="gha-activity-icon"><span class="octicon octicon-{{icon}}"></span></div>\
|
||||||
|
<div class="gha-message"><div class="gha-time">{{{timeString}}}</div>{{{userLink}}} {{{message}}}</div>\
|
||||||
|
<div class="gha-clear"></div>\
|
||||||
|
</div>',
|
||||||
|
SingleLineActivity: '<div class="gha-activity gha-small">\
|
||||||
|
<div class="gha-activity-icon"><span class="octicon octicon-{{icon}}"></span></div>\
|
||||||
|
<div class="gha-message"><div class="gha-time">{{{timeString}}}</div>{{{userLink}}} {{{message}}}</div>\
|
||||||
|
<div class="gha-clear"></div>\
|
||||||
|
</div>',
|
||||||
|
UserHeader: '<div class="gha-header">\
|
||||||
|
<div class="gha-github-icon"><span class="octicon octicon-mark-github"></span></div>\
|
||||||
|
<div class="gha-user-info{{withoutName}}">{{{userNameLink}}}<p>{{{userLink}}}</p></div>\
|
||||||
|
<div class="gha-gravatar">{{{gravatarLink}}}</div>\
|
||||||
|
</div><div class="gha-push"></div>',
|
||||||
|
Footer: '<div class="gha-footer">Public Activity <a href="https://github.com/caseyscarborough/github-activity" target="_blank">GitHub Activity Stream</a>',
|
||||||
|
NoActivity: '<div class="gha-info">This user does not have any public activity yet.</div>',
|
||||||
|
UserNotFound: '<div class="gha-info">User {{username}} wasn\'t found.</div>',
|
||||||
|
EventsNotFound: '<div class="gha-info">Events for user {{username}} not found.</div>',
|
||||||
|
CommitCommentEvent: 'commented on commit {{{commentLink}}}<br>{{{userGravatar}}}<small>{{comment}}</small>',
|
||||||
|
CreateEvent: 'created {{payload.ref_type}} {{{branchLink}}}{{{repoLink}}}',
|
||||||
|
DeleteEvent: 'deleted {{payload.ref_type}} {{payload.ref}} at {{{repoLink}}}',
|
||||||
|
FollowEvent: 'started following {{{targetLink}}}',
|
||||||
|
ForkEvent: 'forked {{{repoLink}}} to {{{forkLink}}}',
|
||||||
|
GistEvent: '{{actionType}} {{{gistLink}}}',
|
||||||
|
GollumEvent: '{{actionType}} the {{{repoLink}}} wiki<br>{{{userGravatar}}}<small>{{{message}}}</small>',
|
||||||
|
IssueCommentEvent: 'commented on {{issueType}} {{{issueLink}}}<br>{{{userGravatar}}}<small>{{comment}}</small>',
|
||||||
|
IssuesEvent: '{{payload.action}} issue {{{issueLink}}}<br>{{{userGravatar}}}<small>{{payload.issue.title}}</small>',
|
||||||
|
MemberEvent: 'added {{{memberLink}}} to {{{repoLink}}}',
|
||||||
|
PublicEvent: 'open sourced {{{repoLink}}}',
|
||||||
|
PullRequestEvent: '{{payload.action}} pull request {{{pullRequestLink}}}<br>{{{userGravatar}}}<small>{{payload.pull_request.title}}</small>{{{mergeMessage}}}',
|
||||||
|
PullRequestReviewCommentEvent: 'commented on pull request {{{pullRequestLink}}}<br>{{{userGravatar}}}<small>{{comment}}</small>',
|
||||||
|
PushEvent: 'pushed to {{{branchLink}}}{{{repoLink}}}<br>\
|
||||||
|
<ul class="gha-commits">{{#payload.commits}}<li><small>{{{committerGravatar}}} {{{shaLink}}} {{message}}</small></li>{{/payload.commits}}</ul>\
|
||||||
|
<small class="gha-message-commits">{{{commitsMessage}}}</small>',
|
||||||
|
ReleaseEvent: 'released {{{tagLink}}} at {{{repoLink}}}<br>{{{userGravatar}}}<small><span class="octicon octicon-cloud-download"></span> {{{zipLink}}}</small>',
|
||||||
|
WatchEvent: 'starred {{{repoLink}}}'
|
||||||
|
},
|
||||||
|
|
||||||
|
icons = {
|
||||||
|
CommitCommentEvent: 'comment-discussion',
|
||||||
|
CreateEvent_repository: 'repo-create',
|
||||||
|
CreateEvent_tag: 'tag-add',
|
||||||
|
CreateEvent_branch: 'git-branch-create',
|
||||||
|
DeleteEvent: 'repo-delete',
|
||||||
|
FollowEvent: 'person-follow',
|
||||||
|
ForkEvent: 'repo-forked',
|
||||||
|
GistEvent: 'gist',
|
||||||
|
GollumEvent: 'repo',
|
||||||
|
IssuesEvent: 'issue-opened',
|
||||||
|
IssueCommentEvent: 'comment-discussion',
|
||||||
|
MemberEvent: 'person',
|
||||||
|
PublicEvent: 'globe',
|
||||||
|
PullRequestEvent: 'git-pull-request',
|
||||||
|
PullRequestReviewCommentEvent: 'comment-discussion',
|
||||||
|
PushEvent: 'git-commit',
|
||||||
|
ReleaseEvent: 'tag-add',
|
||||||
|
WatchEvent: 'star'
|
||||||
|
},
|
||||||
|
|
||||||
|
singleLineActivities = ['CreateEvent', 'DeleteEvent', 'FollowEvent', 'ForkEvent', 'GistEvent', 'MemberEvent', 'WatchEvent'];
|
2
src/main/resources/static/js/jquery-3.3.1.min.js
vendored
Normal file
169
src/main/resources/static/js/js.cookie.js
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*!
|
||||||
|
* JavaScript Cookie v2.2.0
|
||||||
|
* https://github.com/js-cookie/js-cookie
|
||||||
|
*
|
||||||
|
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
|
||||||
|
* Released under the MIT license
|
||||||
|
*/
|
||||||
|
;(function (factory) {
|
||||||
|
var registeredInModuleLoader = false;
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(factory);
|
||||||
|
registeredInModuleLoader = true;
|
||||||
|
}
|
||||||
|
if (typeof exports === 'object') {
|
||||||
|
module.exports = factory();
|
||||||
|
registeredInModuleLoader = true;
|
||||||
|
}
|
||||||
|
if (!registeredInModuleLoader) {
|
||||||
|
var OldCookies = window.Cookies;
|
||||||
|
var api = window.Cookies = factory();
|
||||||
|
api.noConflict = function () {
|
||||||
|
window.Cookies = OldCookies;
|
||||||
|
return api;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}(function () {
|
||||||
|
function extend() {
|
||||||
|
var i = 0;
|
||||||
|
var result = {};
|
||||||
|
for (; i < arguments.length; i++) {
|
||||||
|
var attributes = arguments[i];
|
||||||
|
for (var key in attributes) {
|
||||||
|
result[key] = attributes[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(converter) {
|
||||||
|
function api(key, value, attributes) {
|
||||||
|
var result;
|
||||||
|
if (typeof document === 'undefined') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write
|
||||||
|
|
||||||
|
if (arguments.length > 1) {
|
||||||
|
attributes = extend({
|
||||||
|
path: '/'
|
||||||
|
}, api.defaults, attributes);
|
||||||
|
|
||||||
|
if (typeof attributes.expires === 'number') {
|
||||||
|
var expires = new Date();
|
||||||
|
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
|
||||||
|
attributes.expires = expires;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're using "expires" because "max-age" is not supported by IE
|
||||||
|
attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = JSON.stringify(value);
|
||||||
|
if (/^[\{\[]/.test(result)) {
|
||||||
|
value = result;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!converter.write) {
|
||||||
|
value = encodeURIComponent(String(value))
|
||||||
|
.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
|
||||||
|
} else {
|
||||||
|
value = converter.write(value, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
key = encodeURIComponent(String(key));
|
||||||
|
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
|
||||||
|
key = key.replace(/[\(\)]/g, escape);
|
||||||
|
|
||||||
|
var stringifiedAttributes = '';
|
||||||
|
|
||||||
|
for (var attributeName in attributes) {
|
||||||
|
if (!attributes[attributeName]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stringifiedAttributes += '; ' + attributeName;
|
||||||
|
if (attributes[attributeName] === true) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stringifiedAttributes += '=' + attributes[attributeName];
|
||||||
|
}
|
||||||
|
return (document.cookie = key + '=' + value + stringifiedAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
result = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// To prevent the for loop in the first place assign an empty array
|
||||||
|
// in case there are no cookies at all. Also prevents odd result when
|
||||||
|
// calling "get()"
|
||||||
|
var cookies = document.cookie ? document.cookie.split('; ') : [];
|
||||||
|
var rdecode = /(%[0-9A-Z]{2})+/g;
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
for (; i < cookies.length; i++) {
|
||||||
|
var parts = cookies[i].split('=');
|
||||||
|
var cookie = parts.slice(1).join('=');
|
||||||
|
|
||||||
|
if (!this.json && cookie.charAt(0) === '"') {
|
||||||
|
cookie = cookie.slice(1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var name = parts[0].replace(rdecode, decodeURIComponent);
|
||||||
|
cookie = converter.read ?
|
||||||
|
converter.read(cookie, name) : converter(cookie, name) ||
|
||||||
|
cookie.replace(rdecode, decodeURIComponent);
|
||||||
|
|
||||||
|
if (this.json) {
|
||||||
|
try {
|
||||||
|
cookie = JSON.parse(cookie);
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === name) {
|
||||||
|
result = cookie;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!key) {
|
||||||
|
result[name] = cookie;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
api.set = api;
|
||||||
|
api.get = function (key) {
|
||||||
|
return api.call(api, key);
|
||||||
|
};
|
||||||
|
api.getJSON = function () {
|
||||||
|
return api.apply({
|
||||||
|
json: true
|
||||||
|
}, [].slice.call(arguments));
|
||||||
|
};
|
||||||
|
api.defaults = {};
|
||||||
|
|
||||||
|
api.remove = function (key, attributes) {
|
||||||
|
api(key, '', extend(attributes, {
|
||||||
|
expires: -1
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
api.withConverter = init;
|
||||||
|
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
|
return init(function () {
|
||||||
|
});
|
||||||
|
}));
|
18
src/main/resources/static/js/loading.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
setInterval("loop()", 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
function loop() {
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "/api/isReady",
|
||||||
|
success: function (data) {
|
||||||
|
console.log("Ready");
|
||||||
|
debugger;
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
console.log("Not ready");
|
||||||
|
});
|
||||||
|
}
|
85
src/main/resources/static/js/login.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
var input_name;
|
||||||
|
var input_psw;
|
||||||
|
var btn_submit;
|
||||||
|
|
||||||
|
|
||||||
|
$(document).ready(() => {
|
||||||
|
|
||||||
|
$("#login_form").submit(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
tryConnection();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
input_name = $("#user_input");
|
||||||
|
input_psw = $("#password_input");
|
||||||
|
btn_submit = $("#btn-submit-connect");
|
||||||
|
|
||||||
|
input_name.on("input", function () {
|
||||||
|
if (input_name.val() !== "" && input_psw.val() !== "") {
|
||||||
|
popInSubmit();
|
||||||
|
} else {
|
||||||
|
popOutSubmit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
input_psw.on("input", function () {
|
||||||
|
if (input_name.val() !== "" && input_psw.val() !== "") {
|
||||||
|
popInSubmit();
|
||||||
|
} else {
|
||||||
|
popOutSubmit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function popOutSubmit() {
|
||||||
|
if (btn_submit.hasClass("scale-in")) {
|
||||||
|
btn_submit.removeClass("scale-in");
|
||||||
|
btn_submit.addClass("scale-out");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function popInSubmit() {
|
||||||
|
if (btn_submit.hasClass("scale-out")) {
|
||||||
|
btn_submit.removeClass("scale-out");
|
||||||
|
btn_submit.addClass("scale-in");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function tryConnection() {
|
||||||
|
|
||||||
|
var request = {name: input_name.val(), password: input_psw.val()};
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: 'application/json',
|
||||||
|
url: "/api/userManagement/requestToken",
|
||||||
|
data: JSON.stringify(request),
|
||||||
|
success: function (data) {
|
||||||
|
console.log(data);
|
||||||
|
Cookies.set('token', data.token, {expires: 31});
|
||||||
|
Cookies.set('name', data.name, {expires: 31});
|
||||||
|
window.location.reload(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
console.log(data);
|
||||||
|
switch (data.responseJSON.error) {
|
||||||
|
case "user":
|
||||||
|
input_name.addClass("invalid");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "password":
|
||||||
|
input_psw.addClass("invalid");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
12806
src/main/resources/static/js/materialize.js
vendored
Normal file
6
src/main/resources/static/js/materialize.min.js
vendored
Normal file
632
src/main/resources/static/js/music.js
Normal file
@ -0,0 +1,632 @@
|
|||||||
|
let savedPlaylist;
|
||||||
|
let error = false;
|
||||||
|
let state;
|
||||||
|
let disconected = false;
|
||||||
|
let modal_loading;
|
||||||
|
let btn_play;
|
||||||
|
let btn_stop;
|
||||||
|
let btn_next;
|
||||||
|
let btn_info;
|
||||||
|
let btn_disconnect_music;
|
||||||
|
let btn_flush;
|
||||||
|
let btn_add;
|
||||||
|
let switchAutoFlow;
|
||||||
|
let loadingFlag = true;
|
||||||
|
let musicLoadFlag = false;
|
||||||
|
let guild;
|
||||||
|
let interval;
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
if (Cookies.get('guild') !== undefined) {
|
||||||
|
|
||||||
|
guild = Cookies.get('guild');
|
||||||
|
btn_play = $('#btn_play');
|
||||||
|
btn_stop = $('#btn_stop');
|
||||||
|
btn_next = $('#btn_next');
|
||||||
|
btn_info = $('#btn_info');
|
||||||
|
btn_disconnect_music = $('#btn_disconnect');
|
||||||
|
btn_flush = $('#flush_btn');
|
||||||
|
btn_add = $('#add_btn');
|
||||||
|
switchAutoFlow = $("#autoflow");
|
||||||
|
|
||||||
|
|
||||||
|
M.Modal.init($('#modalAdd').get(0));
|
||||||
|
|
||||||
|
$('#modal_current_info').modal();
|
||||||
|
|
||||||
|
$('#modalChanels').modal({
|
||||||
|
dismissible: false // Modal can be dismissed by clicking outside of the modal
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
modal_loading = M.Modal.init($('#modal_loading').get(0), {dismissible: false});
|
||||||
|
modal_loading.open();
|
||||||
|
$('#tabs-swipe-demo').tabs();
|
||||||
|
|
||||||
|
|
||||||
|
$('.dropdown-button').dropdown({
|
||||||
|
inDuration: 300,
|
||||||
|
outDuration: 225,
|
||||||
|
constrainWidth: false, // Does not change width of dropdown to that of the activator
|
||||||
|
hover: false, // Activate on hover
|
||||||
|
gutter: 0, // Spacing from edge
|
||||||
|
belowOrigin: false, // Displays dropdown below the button
|
||||||
|
alignment: 'left', // Displays dropdown with edge aligned to the left of button
|
||||||
|
stopPropagation: false // Stops event propagation
|
||||||
|
});
|
||||||
|
|
||||||
|
listeners();
|
||||||
|
getCurentMusic();
|
||||||
|
interval = setInterval("getCurentMusic()", 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function getCurentMusic() {
|
||||||
|
$.get("api/music/getAllInfo?guild=" + guild, function (data) {
|
||||||
|
}).done(function (data) {
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
error = false;
|
||||||
|
M.Toast.dismissAll();
|
||||||
|
}
|
||||||
|
state = data.currentMusic.state;
|
||||||
|
switch (data.currentMusic.state) {
|
||||||
|
case "STOP":
|
||||||
|
disconected = false;
|
||||||
|
$('#modalChanels').modal('close');
|
||||||
|
$('#music_text').text("Connected on Vocal Channel");
|
||||||
|
|
||||||
|
if (!$('#music_progress').hasClass("determinate")) {
|
||||||
|
$('#music_progress').addClass("determinate").removeClass("indeterminate");
|
||||||
|
}
|
||||||
|
$('#music_progress').width("0%");
|
||||||
|
if (Cookies.get('token') !== undefined) {
|
||||||
|
disableBtn(btn_stop);
|
||||||
|
disableBtn(btn_info);
|
||||||
|
enableBtn(btn_add);
|
||||||
|
enableBtn(btn_flush);
|
||||||
|
enableBtn(btn_play);
|
||||||
|
enableBtn(btn_next);
|
||||||
|
enableBtn(btn_disconnect_music);
|
||||||
|
} else {
|
||||||
|
disableBtn(btn_play);
|
||||||
|
disableBtn(btn_stop);
|
||||||
|
disableBtn(btn_info);
|
||||||
|
disableBtn(btn_add);
|
||||||
|
disableBtn(btn_flush);
|
||||||
|
disableBtn(btn_next);
|
||||||
|
disableBtn(btn_disconnect_music);
|
||||||
|
}
|
||||||
|
btn_play.children().text("play_arrow");
|
||||||
|
$('#music_img').attr("src", "/img/no_music.jpg");
|
||||||
|
$('#total_time').text("00:00");
|
||||||
|
$('#current_time').text("00:00");
|
||||||
|
btn_play.removeClass("amber");
|
||||||
|
btn_play.addClass("green");
|
||||||
|
if (savedPlaylist != null) {
|
||||||
|
$('#playlist_list').empty();
|
||||||
|
savedPlaylist = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "PLAYING":
|
||||||
|
disconected = false;
|
||||||
|
$('#modalChanels').modal('close');
|
||||||
|
btn_play.children().text("pause");
|
||||||
|
btn_play.removeClass("green");
|
||||||
|
btn_play.addClass("amber");
|
||||||
|
updateControl(data.currentMusic);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "PAUSE":
|
||||||
|
disconected = false;
|
||||||
|
$('#modalChanels').modal('close');
|
||||||
|
btn_play.children().text("play_arrow");
|
||||||
|
btn_play.removeClass("amber");
|
||||||
|
btn_play.addClass("green");
|
||||||
|
btn_play.addClass("green");
|
||||||
|
updateControl(data.currentMusic);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "LOADING":
|
||||||
|
disconected = false;
|
||||||
|
$('#modalChanels').modal('close');
|
||||||
|
updateControl(data.currentMusic);
|
||||||
|
if ($('#music_progress').hasClass("determinate")) {
|
||||||
|
$('#music_progress').addClass("indeterminate").removeClass("determinate");
|
||||||
|
}
|
||||||
|
if (!musicLoadFlag) {
|
||||||
|
clearInterval(interval);
|
||||||
|
interval = setInterval("getCurentMusic()", 200);
|
||||||
|
musicLoadFlag = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "DISCONNECTED":
|
||||||
|
$('#music_text').text("Disconnected from Vocal");
|
||||||
|
|
||||||
|
if (!$('#music_progress').hasClass("determinate")) {
|
||||||
|
$('#music_progress').addClass("determinate").removeClass("indeterminate");
|
||||||
|
}
|
||||||
|
$('#music_progress').width("0%");
|
||||||
|
|
||||||
|
$('#btn_play').children().text("play_arrow");
|
||||||
|
|
||||||
|
disableBtn(btn_play);
|
||||||
|
disableBtn(btn_stop);
|
||||||
|
disableBtn(btn_info);
|
||||||
|
disableBtn(btn_add);
|
||||||
|
disableBtn(btn_flush);
|
||||||
|
disableBtn(btn_next);
|
||||||
|
disableBtn(btn_disconnect_music);
|
||||||
|
|
||||||
|
$('#music_img').attr("src", "/img/disconnected.png");
|
||||||
|
if (Cookies.get('token') != undefined) {
|
||||||
|
if (!disconected) {
|
||||||
|
getChannels();
|
||||||
|
disconected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (savedPlaylist != null) {
|
||||||
|
$('#playlist_list').empty();
|
||||||
|
savedPlaylist = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (switchAutoFlow.is(':checked') !== data.currentMusic.autoflow)
|
||||||
|
switchAutoFlow.prop('checked', data.currentMusic.autoflow);
|
||||||
|
if (data.currentMusic.state !== "DISCONNECTED" && data.currentMusic.state !== "STOP") {
|
||||||
|
getPlayList(data.playlist.list);
|
||||||
|
if (data.currentMusic.state !== "LOADING") {
|
||||||
|
$(".ctl-btn").removeClass("disabled");
|
||||||
|
if (musicLoadFlag) {
|
||||||
|
clearInterval(interval);
|
||||||
|
interval = setInterval("getCurentMusic()", 1000);
|
||||||
|
musicLoadFlag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (loadingFlag) {
|
||||||
|
modal_loading.close();
|
||||||
|
loadingFlag = false;
|
||||||
|
}
|
||||||
|
$(".ctl-btn").removeClass("disabled");
|
||||||
|
if (musicLoadFlag) {
|
||||||
|
clearInterval(interval);
|
||||||
|
interval = setInterval("getCurentMusic()", 1000);
|
||||||
|
musicLoadFlag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
if (!error) {
|
||||||
|
error = true;
|
||||||
|
console.error("Connection lost, I keep trying to refresh!");
|
||||||
|
M.toast({
|
||||||
|
html: " <i class=\"material-icons\" style='margin-right: 10px'>warning</i> Connection Lost!",
|
||||||
|
classes: 'red',
|
||||||
|
displayLength: 99999999
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlayList(data) {
|
||||||
|
|
||||||
|
if (data != null && data.length != 0) {
|
||||||
|
var noUpdate = comparePlaylist(data, savedPlaylist);
|
||||||
|
if (!noUpdate) {
|
||||||
|
savedPlaylist = data;
|
||||||
|
$('#playlist_list').empty();
|
||||||
|
|
||||||
|
data.forEach(function (element) {
|
||||||
|
var template = $('#playlist_template').clone();
|
||||||
|
template.removeAttr("id");
|
||||||
|
template.removeAttr("style");
|
||||||
|
var content = template.html();
|
||||||
|
content = content.replace("@title", element.audioTrackInfo.title);
|
||||||
|
content = content.replace("@author", element.audioTrackInfo.author);
|
||||||
|
content = content.replace("@lenght", msToTime(element.audioTrackInfo.length));
|
||||||
|
content = content.replace(/@url/g, element.audioTrackInfo.uri);
|
||||||
|
content = content.replace(/@user/g, element.user);
|
||||||
|
template.html(content);
|
||||||
|
|
||||||
|
$('#playlist_list').append(template);
|
||||||
|
$('.collapsible').collapsible();
|
||||||
|
|
||||||
|
});
|
||||||
|
$(".btn_dell_playlist").click(function () {
|
||||||
|
var command = {
|
||||||
|
command: "DELL",
|
||||||
|
url: $(this).attr("data_url")
|
||||||
|
};
|
||||||
|
sendCommand(command, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$('#playlist_list').empty();
|
||||||
|
savedPlaylist = {};
|
||||||
|
}
|
||||||
|
if (loadingFlag) {
|
||||||
|
modal_loading.close();
|
||||||
|
loadingFlag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChannels() {
|
||||||
|
$.get("api/music/getChanel?guild=" + guild, function (data) {
|
||||||
|
}).done(function (data) {
|
||||||
|
|
||||||
|
$('#channelForm').empty();
|
||||||
|
data.forEach(function (element) {
|
||||||
|
var template = $('#radioTemplate').clone();
|
||||||
|
template.removeAttr("id");
|
||||||
|
template.removeAttr("style");
|
||||||
|
var content = template.html();
|
||||||
|
content = content.replace("@name", element.name);
|
||||||
|
content = content.replace(/@id/g, element.id);
|
||||||
|
template.html(content);
|
||||||
|
|
||||||
|
$('#channelForm').append(template);
|
||||||
|
});
|
||||||
|
$('#btn_ok_channel').addClass("disabled");
|
||||||
|
$('#modalChanels').modal('open');
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
if (!error) {
|
||||||
|
M.toast({
|
||||||
|
html: " <i class=\"material-icons\" style='margin-right: 10px'>warning</i> Connection Lost!",
|
||||||
|
classes: 'red',
|
||||||
|
displayLength: 99999999
|
||||||
|
});
|
||||||
|
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateModal(data) {
|
||||||
|
$('#modal_title').text("Title: " + data.info.audioTrackInfo.title);
|
||||||
|
$('#modal_author').text("Author: " + data.info.audioTrackInfo.author);
|
||||||
|
$('#modal_lenght').text("Duration: " + msToTime(data.info.audioTrackInfo.length));
|
||||||
|
$('#modal_url').html("<div>URL: <a target=\"_blank\" href=\"" + data.info.audioTrackInfo.uri + "\">" + data.info.audioTrackInfo.uri + "</a></div>");
|
||||||
|
//
|
||||||
|
$('#modal_submit').text("Submitted by: " + data.info.user);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateControl(data) {
|
||||||
|
|
||||||
|
if ($('#music_text').text() !== data.info.audioTrackInfo.title) {
|
||||||
|
$('#music_text').text(data.info.audioTrackInfo.title);
|
||||||
|
}
|
||||||
|
var percent = (data.currentPos / data.info.audioTrackInfo.length) * 100;
|
||||||
|
|
||||||
|
$('#music_progress').width(percent + "%");
|
||||||
|
|
||||||
|
if (data.state !== "LOADING") {
|
||||||
|
if (Cookies.get('token') !== undefined) {
|
||||||
|
enableBtn(btn_play);
|
||||||
|
enableBtn(btn_stop);
|
||||||
|
enableBtn(btn_info);
|
||||||
|
enableBtn(btn_add);
|
||||||
|
enableBtn(btn_flush);
|
||||||
|
enableBtn(btn_next);
|
||||||
|
enableBtn(btn_disconnect_music);
|
||||||
|
} else {
|
||||||
|
disableBtn(btn_play);
|
||||||
|
disableBtn(btn_stop);
|
||||||
|
disableBtn(btn_info);
|
||||||
|
disableBtn(btn_add);
|
||||||
|
disableBtn(btn_flush);
|
||||||
|
disableBtn(btn_next);
|
||||||
|
disableBtn(btn_disconnect_music);
|
||||||
|
}
|
||||||
|
if (!$('#music_progress').hasClass("determinate")) {
|
||||||
|
$('#music_progress').addClass("determinate").removeClass("indeterminate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$('#music_img').attr("src", "https://img.youtube.com/vi/" + data.info.audioTrackInfo.identifier + "/hqdefault.jpg");
|
||||||
|
$('#total_time').text(msToTime(data.info.audioTrackInfo.length));
|
||||||
|
$('#current_time').text(msToTime(data.currentPos));
|
||||||
|
updateModal(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendCommand(command, modal) {
|
||||||
|
clearInterval(interval);
|
||||||
|
interval = null;
|
||||||
|
if (modal) {
|
||||||
|
modal_loading.open();
|
||||||
|
|
||||||
|
}
|
||||||
|
$(".ctl-btn").addClass("disabled");
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: 'application/json',
|
||||||
|
url: "/api/music/command?guild=" + guild,
|
||||||
|
data: JSON.stringify(command),
|
||||||
|
success: function (data) {
|
||||||
|
loadingFlag = true;
|
||||||
|
getCurentMusic();
|
||||||
|
if (interval != null)
|
||||||
|
clearInterval(interval);
|
||||||
|
interval = setInterval("getCurentMusic()", 1000);
|
||||||
|
|
||||||
|
if (command.command === "ADD") {
|
||||||
|
M.toast({
|
||||||
|
html: " <i class=\"material-icons\" style='margin-right: 10px'>check_circle</i> Video added to playlist!",
|
||||||
|
classes: 'green',
|
||||||
|
displayLength: 5000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
console.log(data);
|
||||||
|
modal_loading.close();
|
||||||
|
if (data.responseJSON.error === "token") {
|
||||||
|
Cookies.remove('token');
|
||||||
|
Cookies.remove('name');
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
M.toast({
|
||||||
|
html: " <i class=\"material-icons\" style='margin-right: 10px'>warning</i> Command fail!",
|
||||||
|
classes: 'red',
|
||||||
|
displayLength: 99999999
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$(".ctl-btn").removeClass("disabled");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function comparePlaylist(list1, list2) {
|
||||||
|
if (list1 == null || list2 == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (list1.length !== list2.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (let i = 0; i < list1.length; i++) {
|
||||||
|
if (list1[i].audioTrackInfo.uri !== list2[i].audioTrackInfo.uri)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function search() {
|
||||||
|
let input_search = $('#input_search');
|
||||||
|
let list = $("#search_result");
|
||||||
|
let load = $("#search_load");
|
||||||
|
disableBtn($('#btn_search'));
|
||||||
|
input_search.attr('disabled', 'disabled');
|
||||||
|
list.removeClass("scale-in");
|
||||||
|
load.removeClass("hide");
|
||||||
|
load.addClass("scale-in");
|
||||||
|
|
||||||
|
$.get("/api/music/search?query=" + input_search.val(), (data) => {
|
||||||
|
list.empty();
|
||||||
|
let url = "https://youtube.com/watch?v=";
|
||||||
|
|
||||||
|
data.forEach((item) => {
|
||||||
|
|
||||||
|
let html =
|
||||||
|
"<li class=\"collection-item avatar\">" +
|
||||||
|
" <img src=\"" + item["imageUrl"] + "\" alt=\"\" class=\"\">" +
|
||||||
|
" <a class=\"title truncate\" href='" + url + item["id"] + "' target=\"_blank\"><b>" + item["title"] + "</b></a>" +
|
||||||
|
" <p class='truncate grey-text text-darken-1'>" + item["channelTittle"] + " <br>" + item["duration"] +
|
||||||
|
" </p>" +
|
||||||
|
" <a href=\"#!\" class=\"secondary-content btn waves-effect waves-light green add-btn-list scale-transition\" id='" + item["id"] + "'><i class=\"material-icons \">add_circle_outline</i></a>" +
|
||||||
|
" </div>" +
|
||||||
|
"</li>";
|
||||||
|
|
||||||
|
|
||||||
|
list.append(html)
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".add-btn-list").click(addListClick);
|
||||||
|
// list.removeClass("hide");
|
||||||
|
|
||||||
|
load.removeClass("scale-in");
|
||||||
|
load.addClass("hide");
|
||||||
|
list.addClass("scale-in");
|
||||||
|
enableBtn($('#btn_search'));
|
||||||
|
input_search.removeAttr("disabled");
|
||||||
|
|
||||||
|
}).fail((data) => {
|
||||||
|
if (data.status === 401) {
|
||||||
|
M.toast({
|
||||||
|
html: " <i class=\"material-icons\" style='margin-right: 10px'>warning</i> Unauthorized, please re-login.",
|
||||||
|
classes: 'red',
|
||||||
|
displayLength: 99999999
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
M.toast({
|
||||||
|
html: " <i class=\"material-icons\" style='margin-right: 10px'>warning</i>Internal server error, please contact dev.",
|
||||||
|
classes: 'red',
|
||||||
|
displayLength: 99999999
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
list.empty();
|
||||||
|
load.removeClass("scale-in");
|
||||||
|
load.addClass("hide");
|
||||||
|
enableBtn($('#btn_search'));
|
||||||
|
enableBtn(input_search);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function addListClick(event) {
|
||||||
|
let button;
|
||||||
|
if (event.target.nodeName === "I") {
|
||||||
|
button = event.target.parentNode;
|
||||||
|
} else
|
||||||
|
button = event.target;
|
||||||
|
button.classList.add("scale-out");
|
||||||
|
|
||||||
|
let command = {
|
||||||
|
command: "ADD",
|
||||||
|
url: button.id,
|
||||||
|
playlistLimit: "300",
|
||||||
|
onHead: !$('#bottom').is(':checked')
|
||||||
|
};
|
||||||
|
sendCommand(command, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ytTimeToTime(duration) {
|
||||||
|
let hours;
|
||||||
|
let minutes;
|
||||||
|
let seconds;
|
||||||
|
if (duration === "PT0S")
|
||||||
|
return "🔴 LIVE";
|
||||||
|
if (duration.endsWith("Video(s)"))
|
||||||
|
return duration;
|
||||||
|
if (duration.includes("H"))
|
||||||
|
hours = parseInt(duration.match(/\d*H/)[0].replace("H", ""), 10);
|
||||||
|
else
|
||||||
|
hours = 0;
|
||||||
|
|
||||||
|
if (duration.includes("M"))
|
||||||
|
minutes = parseInt(duration.match(/\d*M/)[0].replace("M", ""), 10);
|
||||||
|
else
|
||||||
|
minutes = 0;
|
||||||
|
|
||||||
|
if (duration.includes("S"))
|
||||||
|
seconds = parseInt(duration.match(/\d*S/)[0].replace("S", ""), 10);
|
||||||
|
else
|
||||||
|
seconds = 0;
|
||||||
|
|
||||||
|
hours = (hours < 10) ? "0" + hours : hours;
|
||||||
|
minutes = (minutes < 10) ? "0" + minutes : minutes;
|
||||||
|
seconds = (seconds < 10) ? "0" + seconds : seconds;
|
||||||
|
if (hours > 0)
|
||||||
|
return hours + ":" + minutes + ":" + seconds;
|
||||||
|
else
|
||||||
|
return minutes + ":" + seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function msToTime(duration) {
|
||||||
|
var milliseconds = parseInt((duration % 1000) / 100)
|
||||||
|
, seconds = parseInt((duration / 1000) % 60)
|
||||||
|
, minutes = parseInt((duration / (1000 * 60)) % 60)
|
||||||
|
, hours = parseInt((duration / (1000 * 60 * 60)) % 24);
|
||||||
|
|
||||||
|
hours = (hours < 10) ? "0" + hours : hours;
|
||||||
|
minutes = (minutes < 10) ? "0" + minutes : minutes;
|
||||||
|
seconds = (seconds < 10) ? "0" + seconds : seconds;
|
||||||
|
if (hours > 0)
|
||||||
|
return hours + ":" + minutes + ":" + seconds;
|
||||||
|
else
|
||||||
|
return minutes + ":" + seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
function listeners() {
|
||||||
|
|
||||||
|
|
||||||
|
$('#btn_play').click(function () {
|
||||||
|
switch (state) {
|
||||||
|
case "PLAYING":
|
||||||
|
sendCommand({command: "PAUSE"}, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "PAUSE":
|
||||||
|
sendCommand({command: "PLAY"}, true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sendCommand({command: "PLAY"}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btn_search').click(search);
|
||||||
|
|
||||||
|
$("form").submit(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
search();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btn_next').click(function () {
|
||||||
|
sendCommand({command: "NEXT"}, false);
|
||||||
|
})
|
||||||
|
$('#btn_stop').click(function () {
|
||||||
|
sendCommand({command: "STOP"}, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('#input_search').on("input", function () {
|
||||||
|
if ($('#input_search').val() == "") {
|
||||||
|
disableBtn($('#btn_search'));
|
||||||
|
} else {
|
||||||
|
enableBtn($('#btn_search'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('#modalChanels').change(function () {
|
||||||
|
if ($('#btn_ok_channel').hasClass("disabled")) {
|
||||||
|
$('#btn_ok_channel').removeClass("disabled");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#flush_btn').click(function () {
|
||||||
|
var command = {
|
||||||
|
command: "FLUSH"
|
||||||
|
};
|
||||||
|
sendCommand(command, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btn_ok_channel').click(function () {
|
||||||
|
|
||||||
|
var command = {
|
||||||
|
command: "CONNECT",
|
||||||
|
chanelId: $('input[name=vocalRadio]:checked').val()
|
||||||
|
};
|
||||||
|
sendCommand(command, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btn_disconnect').click(function () {
|
||||||
|
sendCommand({command: "DISCONNECT"}, true)
|
||||||
|
});
|
||||||
|
|
||||||
|
switchAutoFlow.click(function () {
|
||||||
|
if (switchAutoFlow.is(':checked')) {
|
||||||
|
sendCommand({command: 'AUTOFLOWON'}, false)
|
||||||
|
} else
|
||||||
|
sendCommand({command: 'AUTOFLOWOFF'}, false)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function disableBtn(btn) {
|
||||||
|
if (!btn.hasClass("disabled")) {
|
||||||
|
btn.addClass("disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableBtn(btn) {
|
||||||
|
if (btn.hasClass("disabled")) {
|
||||||
|
btn.removeClass("disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
198
src/main/resources/static/js/navabar.js
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
var nav_bar_account_link;
|
||||||
|
var connected_link = "<a class=\"dropdown-account dropdown-trigger\" data-target=\"dropdown_connected\"><i class=\"material-icons green-text\">account_box</i></a>";
|
||||||
|
var disconnected_link = "<a class=\"waves-effect waves-light modal-trigger\" href=\"#modal_connection\"><i class=\"material-icons red-text\">account_box</i></a>";
|
||||||
|
var btn_disconnect;
|
||||||
|
var nav_name;
|
||||||
|
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.tooltipped').tooltip();
|
||||||
|
|
||||||
|
$('#modal_guild').modal({
|
||||||
|
dismissible: false // Modal can be dismissed by clicking outside of the modal
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modal_internet').modal({
|
||||||
|
dismissible: false // Modal can be dismissed by clicking outside of the modal
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
nav_bar_account_link = $("#nav-bar-account");
|
||||||
|
btn_disconnect = $(".nav-disconnect");
|
||||||
|
nav_name = $("#nav-name");
|
||||||
|
navListeners();
|
||||||
|
|
||||||
|
|
||||||
|
checkConnection();
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function connected() {
|
||||||
|
console.log("Connected!");
|
||||||
|
console.log("Checking token...");
|
||||||
|
console.log(window.location.href);
|
||||||
|
if (!window.location.href.includes("oauthCallback")) {
|
||||||
|
checkToken();
|
||||||
|
} else {
|
||||||
|
console.log("Oauth page skip check token");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function disconnected() {
|
||||||
|
console.log("Disconnected");
|
||||||
|
nav_bar_account_link.html(disconnected_link);
|
||||||
|
var modalConnection = $('#modal_connection');
|
||||||
|
modalConnection.modal({
|
||||||
|
dismissible: false // Modal can be dismissed by clicking outside of the modal
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function navListeners() {
|
||||||
|
|
||||||
|
btn_disconnect.click(function () {
|
||||||
|
Cookies.remove('token');
|
||||||
|
Cookies.remove('name');
|
||||||
|
Cookies.remove('guild');
|
||||||
|
window.location.reload(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#guild_form').change(function () {
|
||||||
|
if ($('#btn_ok_guild').hasClass("disabled")) {
|
||||||
|
$('#btn_ok_guild').removeClass("disabled");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#btn_ok_guild').click(function () {
|
||||||
|
guild = $('input[name=guildRadio]:checked').val();
|
||||||
|
Cookies.set('guild', guild, {expires: 31});
|
||||||
|
window.location.reload(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.guild_change').click(function () {
|
||||||
|
let id = this.getAttribute("data-id");
|
||||||
|
Cookies.set('guild', id, {expires: 31});
|
||||||
|
window.location.reload(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.nav-change-guild').click(function () {
|
||||||
|
Cookies.remove('guild');
|
||||||
|
window.location.reload(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGuild() {
|
||||||
|
$.get("api/userManagement/getGuilds", function (data) {
|
||||||
|
}).done(function (data) {
|
||||||
|
console.log(data);
|
||||||
|
$('#guild_form').empty();
|
||||||
|
if (data.length === 0 && location.pathname !== "/")
|
||||||
|
window.location.replace("/");
|
||||||
|
if (data.length === 0) {
|
||||||
|
return;
|
||||||
|
} else if (data.length === 1) {
|
||||||
|
Cookies.set('guild', data[0].id, {expires: 31});
|
||||||
|
window.location.reload(true);
|
||||||
|
}
|
||||||
|
data.forEach(function (element) {
|
||||||
|
var template = $('#radioTemplateGuild').clone();
|
||||||
|
template.removeAttr("id");
|
||||||
|
template.removeAttr("style");
|
||||||
|
var content = template.html();
|
||||||
|
content = content.replace("@name", element.name);
|
||||||
|
content = content.replace(/@id/g, element.id);
|
||||||
|
content = content.replace(/@url/g, element.imageUrl == null ? "https://discordapp.com/assets/dd4dbc0016779df1378e7812eabaa04d.png" : element.imageUrl);
|
||||||
|
template.html(content);
|
||||||
|
|
||||||
|
$('#guild_form').append(template);
|
||||||
|
});
|
||||||
|
$('#modal_guild').modal('open');
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
if (!error) {
|
||||||
|
alert("Com error, please refresh.");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function checkConnection() {
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "/api/isReady",
|
||||||
|
success: function (data) {
|
||||||
|
console.log("Connection Ok");
|
||||||
|
console.log(Cookies.get('token'));
|
||||||
|
|
||||||
|
if (Cookies.get('token') === undefined) {
|
||||||
|
disconnected()
|
||||||
|
} else {
|
||||||
|
connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
console.error("Connection fail!");
|
||||||
|
$('#modal_internet').modal('open');
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function checkToken() {
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "/api/userManagement/checkToken",
|
||||||
|
success: function (data) {
|
||||||
|
console.debug("...token is valid.");
|
||||||
|
nav_bar_account_link.html(connected_link);
|
||||||
|
$('.dropdown-account').dropdown({
|
||||||
|
constrainWidth: false, // Does not change width of dropdown to that of the activator
|
||||||
|
coverTrigger: false, // Displays dropdown below the button
|
||||||
|
alignment: 'left', // Displays dropdown with edge aligned to the left of button
|
||||||
|
stopPropagation: false // Stops event propagation
|
||||||
|
}
|
||||||
|
);
|
||||||
|
nav_name.text(Cookies.get('name'));
|
||||||
|
$('#nav-mobile').sidenav({
|
||||||
|
menuWidth: 400, // Default is 300
|
||||||
|
edge: 'left', // Choose the horizontal origin
|
||||||
|
closeOnClick: false, // Closes side-nav on <a> clicks, useful for Angular/Meteor
|
||||||
|
draggable: true // Choose whether you can drag to open on touch screens,
|
||||||
|
});
|
||||||
|
if (Cookies.get('guild') === undefined) {
|
||||||
|
getGuild()
|
||||||
|
} else {
|
||||||
|
$('#drop-trigger-guilds').dropdown({
|
||||||
|
constrainWidth: false, // Does not change width of dropdown to that of the activator
|
||||||
|
coverTrigger: false, // Displays dropdown below the button
|
||||||
|
alignment: 'left', // Displays dropdown with edge aligned to the left of button
|
||||||
|
stopPropagation: false // Stops event propagation
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
console.error("...token is invalid !");
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
Cookies.remove('token');
|
||||||
|
Cookies.remove('name');
|
||||||
|
Cookies.remove('guild');
|
||||||
|
window.location.reload(true);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
31
src/main/resources/static/js/oauthCallback.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
var hash = window.location.hash.replace("#", "").split("&");
|
||||||
|
var discordToken = "";
|
||||||
|
|
||||||
|
debugger;
|
||||||
|
|
||||||
|
hash.forEach(function (value) {
|
||||||
|
if (value.indexOf("access_token") !== -1) {
|
||||||
|
discordToken = value.split("=")[1];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (discordToken !== "") {
|
||||||
|
console.log(discordToken);
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: 'application/json',
|
||||||
|
url: "/api/userManagement/oauthLogin?token=" + discordToken,
|
||||||
|
success: function (data) {
|
||||||
|
console.log(data);
|
||||||
|
Cookies.set('token', data.token, {expires: 31});
|
||||||
|
Cookies.set('name', data.name, {expires: 31});
|
||||||
|
window.location = "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window.location = "/";
|
||||||
|
}
|
164
src/main/resources/static/js/register.js
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
var ok_passwrd = false;
|
||||||
|
$(document).ready(function () {
|
||||||
|
var baseUrl = window.location.protocol + "//" + window.location.host + window.location.pathname;
|
||||||
|
console.log(baseUrl);
|
||||||
|
|
||||||
|
var sendBtn = $('#sendBtn');
|
||||||
|
|
||||||
|
|
||||||
|
$('#name').on("input", function () {
|
||||||
|
if ($('#name').val() === "") {
|
||||||
|
if (sendBtn.hasClass("scale-in")) {
|
||||||
|
sendBtn.removeClass("scale-in");
|
||||||
|
sendBtn.addClass("scale-out");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (sendBtn.hasClass("scale-out") && ok_passwrd) {
|
||||||
|
sendBtn.removeClass("scale-out");
|
||||||
|
sendBtn.addClass("scale-in");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var passwrd = $('#passwrd');
|
||||||
|
var confirm = $('#passwrd2');
|
||||||
|
passwrd.on("input", function () {
|
||||||
|
if ((passwrd.val() === confirm.val()) && passwrd.val() !== '') {
|
||||||
|
if (passwrd.hasClass("invalid")) {
|
||||||
|
passwrd.addClass("valid");
|
||||||
|
passwrd.removeClass("invalid");
|
||||||
|
confirm.addClass("valid");
|
||||||
|
confirm.removeClass("invalid");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
if ($('#name').val() !== "") {
|
||||||
|
if (sendBtn.hasClass("scale-out")) {
|
||||||
|
sendBtn.removeClass("scale-out");
|
||||||
|
sendBtn.addClass("scale-in");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok_passwrd = true;
|
||||||
|
} else {
|
||||||
|
if (!passwrd.hasClass("invalid")) {
|
||||||
|
passwrd.addClass("invalid");
|
||||||
|
passwrd.removeClass("valid");
|
||||||
|
confirm.addClass("invalid");
|
||||||
|
confirm.removeClass("valid");
|
||||||
|
|
||||||
|
}
|
||||||
|
if (sendBtn.hasClass("scale-in")) {
|
||||||
|
sendBtn.removeClass("scale-in");
|
||||||
|
sendBtn.addClass("scale-out");
|
||||||
|
}
|
||||||
|
ok_passwrd = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
confirm.on("input", function () {
|
||||||
|
if ((passwrd.val() === confirm.val()) && passwrd.val() !== '') {
|
||||||
|
if (passwrd.hasClass("invalid")) {
|
||||||
|
passwrd.addClass("valid");
|
||||||
|
passwrd.removeClass("invalid");
|
||||||
|
confirm.addClass("valid");
|
||||||
|
confirm.removeClass("invalid");
|
||||||
|
|
||||||
|
}
|
||||||
|
if ($('#name').val() !== "") {
|
||||||
|
if (sendBtn.hasClass("scale-out")) {
|
||||||
|
sendBtn.removeClass("scale-out");
|
||||||
|
sendBtn.addClass("scale-in");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok_passwrd = true;
|
||||||
|
} else {
|
||||||
|
if (!passwrd.hasClass("invalid")) {
|
||||||
|
passwrd.addClass("invalid");
|
||||||
|
passwrd.removeClass("valid");
|
||||||
|
confirm.addClass("invalid");
|
||||||
|
confirm.removeClass("valid");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sendBtn.hasClass("scale-in")) {
|
||||||
|
sendBtn.removeClass("scale-in");
|
||||||
|
sendBtn.addClass("scale-out");
|
||||||
|
}
|
||||||
|
ok_passwrd = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('#sendBtn').click(function () {
|
||||||
|
var name = $('#name').val();
|
||||||
|
var password = $('#passwrd').val();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: 'application/json',
|
||||||
|
url: "/api/userManagement/preRegister",
|
||||||
|
data: JSON.stringify({name: name, password: password}),
|
||||||
|
success: function (data) {
|
||||||
|
console.log(data);
|
||||||
|
window.location.href = baseUrl + "?id=" + data.id
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
console.log(data);
|
||||||
|
if (data.status === 404) {
|
||||||
|
alert("User Not Found!");
|
||||||
|
$('#name').addClass("invalid");
|
||||||
|
$('#name').removeClass("valid");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
alert(data.responseJSON.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modalToken').modal({dismissible: false});
|
||||||
|
if (id !== '') {
|
||||||
|
$('#modalToken').modal('open');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$('#input_preToken').on("input", function () {
|
||||||
|
var sendBtn = $('#preTokenSend');
|
||||||
|
if ($('#input_preToken').val().length < 4) {
|
||||||
|
if (sendBtn.hasClass("scale-in")) {
|
||||||
|
sendBtn.removeClass("scale-in");
|
||||||
|
sendBtn.addClass("scale-out");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (sendBtn.hasClass("scale-out")) {
|
||||||
|
sendBtn.removeClass("scale-out");
|
||||||
|
sendBtn.addClass("scale-in");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('#preTokenSend').click(function () {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: 'application/json',
|
||||||
|
url: "/api/userManagement/confirmAccount",
|
||||||
|
data: JSON.stringify({id: id.toString(), checkToken: $('#input_preToken').val()}),
|
||||||
|
success: function (data) {
|
||||||
|
console.log(data);
|
||||||
|
Cookies.set('token', data.token);
|
||||||
|
Cookies.set('name', data.name);
|
||||||
|
debugger;
|
||||||
|
window.location.href = "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function (data) {
|
||||||
|
console.log(data);
|
||||||
|
alert(data.responseJSON.message);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
80
src/main/resources/static/js/settings.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
var post_json = {settings: []};
|
||||||
|
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
|
||||||
|
$('select').formSelect();
|
||||||
|
modal_loading = $('#modal_loading');
|
||||||
|
modal_loading.modal({
|
||||||
|
dismissible: false
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#sendBtn').click(function () {
|
||||||
|
|
||||||
|
var select = $('.collect-select');
|
||||||
|
select.each(function () {
|
||||||
|
var val = $(this).find("select").val();
|
||||||
|
var id = $(this).attr("id");
|
||||||
|
if (val != null) {
|
||||||
|
post_json["settings"].push({"id": id, "val": val});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var select_multi = $('.collect-select-multiple');
|
||||||
|
select_multi.each(function () {
|
||||||
|
var instance = M.FormSelect.getInstance($(this).find("select")[0]);
|
||||||
|
|
||||||
|
var id = $(this).attr("id");
|
||||||
|
post_json["settings"].push({"id": id, "vals": instance.getSelectedValues()});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var switch_collected = $('.collect-switch');
|
||||||
|
switch_collected.each(function () {
|
||||||
|
var val = $(this).is(':checked').toString();
|
||||||
|
var id = $(this).attr("id");
|
||||||
|
if (val != null) {
|
||||||
|
post_json["settings"].push({"id": id, "val": val});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var text = $('.collect-text');
|
||||||
|
text.each(function () {
|
||||||
|
var val = $(this).val();
|
||||||
|
var id = $(this).attr("id");
|
||||||
|
if (val != null) {
|
||||||
|
post_json["settings"].push({"id": id, "val": val});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
modal_loading.modal('open');
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
contentType: 'application/json',
|
||||||
|
url: "/api/settings",
|
||||||
|
data: JSON.stringify(post_json)
|
||||||
|
|
||||||
|
}).done(function (data) {
|
||||||
|
console.log("ok");
|
||||||
|
M.toast({
|
||||||
|
html: '<i class="small material-icons" style="margin-right: 0.3em">done</i>Save Successful ! ',
|
||||||
|
classes: 'rounded green'
|
||||||
|
});
|
||||||
|
modal_loading.modal('close');
|
||||||
|
}).fail(function (data) {
|
||||||
|
console.log(data);
|
||||||
|
modal_loading.modal('close');
|
||||||
|
M.toast({
|
||||||
|
html: '<i class="small material-icons" style="margin-right: 0.3em">report</i>Save Failed ! ',
|
||||||
|
classes: 'rounded red'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
});
|
11
src/main/resources/static/js/workerRegister.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.addEventListener('load', function () {
|
||||||
|
navigator.serviceWorker.register('/sw.js').then(function (registration) {
|
||||||
|
// Registration was successful
|
||||||
|
console.log('ServiceWorker registration successful with scope: ', registration.scope);
|
||||||
|
}, function (err) {
|
||||||
|
// registration failed :(
|
||||||
|
console.log('ServiceWorker registration failed: ', err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
20
src/main/resources/static/manifest.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"short_name": "Claptrap",
|
||||||
|
"name": "Claptrap Bot",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/img/icon_192.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/img/icon_512.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "512x512"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "#3e2723",
|
||||||
|
"background_color": "#263238"
|
||||||
|
}
|
32
src/main/resources/static/sitemap.xml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||||
|
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
||||||
|
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
|
||||||
|
<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com -->
|
||||||
|
|
||||||
|
|
||||||
|
<url>
|
||||||
|
<loc>https://claptrapbot.com/</loc>
|
||||||
|
<lastmod>2018-12-03T15:47:35+00:00</lastmod>
|
||||||
|
<priority>1.00</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://claptrapbot.com/music</loc>
|
||||||
|
<lastmod>2018-12-03T15:47:35+00:00</lastmod>
|
||||||
|
<priority>0.80</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://claptrapbot.com/login</loc>
|
||||||
|
<lastmod>2018-12-03T15:47:35+00:00</lastmod>
|
||||||
|
<priority>0.80</priority>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://claptrapbot.com/register</loc>
|
||||||
|
<lastmod>2018-12-03T15:47:35+00:00</lastmod>
|
||||||
|
<priority>0.64</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
|
||||||
|
</urlset>
|
86
src/main/resources/static/sw.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
var CACHE_NAME = 'Clap-Trap-Bot-V0.2';
|
||||||
|
var urlsToCache = [
|
||||||
|
'/',
|
||||||
|
'/music',
|
||||||
|
'/register',
|
||||||
|
'/oauthCallback',
|
||||||
|
'/css/materialize.css',
|
||||||
|
'/js/navabar.js',
|
||||||
|
'/js/materialize.js',
|
||||||
|
'/js/jquery-3.3.1.min.js',
|
||||||
|
'/js/js.cookie.js',
|
||||||
|
'/manifest.json'
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
self.addEventListener('install', function (event) {
|
||||||
|
// Perform install steps
|
||||||
|
self.skipWaiting();
|
||||||
|
event.waitUntil(
|
||||||
|
caches.open(CACHE_NAME)
|
||||||
|
.then(function (cache) {
|
||||||
|
console.log('Opened cache');
|
||||||
|
return cache.addAll(urlsToCache);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', function (event) {
|
||||||
|
|
||||||
|
|
||||||
|
var request = event.request;
|
||||||
|
|
||||||
|
event.respondWith(fetch(request).catch(function (reason) {
|
||||||
|
console.error(
|
||||||
|
'[onfetch] Failed. Serving cached offline fallback ' +
|
||||||
|
reason
|
||||||
|
);
|
||||||
|
return caches.open(CACHE_NAME).then(function (cache) {
|
||||||
|
return cache.match(request);
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
event.waitUntil(
|
||||||
|
update(event.request)
|
||||||
|
.then(refresh, function (reason) {
|
||||||
|
console.log("Update fail");
|
||||||
|
console.log(event.request)
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
function update(request) {
|
||||||
|
return caches.match(request).then(function (response) {
|
||||||
|
if (response) {
|
||||||
|
return caches.open(CACHE_NAME).then(function (cache) {
|
||||||
|
return fetch(request).then(function (response) {
|
||||||
|
return cache.put(request, response.clone()).then(function () {
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh(response) {
|
||||||
|
if (response) {
|
||||||
|
return self.clients.matchAll().then(function (clients) {
|
||||||
|
clients.forEach(function (client) {
|
||||||
|
var message = {
|
||||||
|
type: 'refresh',
|
||||||
|
url: response.url,
|
||||||
|
eTag: response.headers.get('eTag')
|
||||||
|
};
|
||||||
|
client.postMessage(JSON.stringify(message));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
10
src/main/resources/static/templates/music_item_playlist.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<li>
|
||||||
|
<div class="collapsible-header"><i class="material-icons">drag_handle</i><h6 class="truncate">@title</h6></div>
|
||||||
|
<div class="collapsible-body">
|
||||||
|
<ul class="collection">
|
||||||
|
<li class="collection-item">Author: @author</li>
|
||||||
|
<li class="collection-item">Duration: @lenght</li>
|
||||||
|
<li class="collection-item">URL: <a>@url</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
92
src/main/resources/templates/error/403.html
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Claptrap Bot</title>
|
||||||
|
<link href="/favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/manifest.json" rel="manifest"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
<style>
|
||||||
|
@media only screen and (max-width: 992px) {
|
||||||
|
.row.valign-wrapper {
|
||||||
|
display: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 992px) {
|
||||||
|
img {
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div th:replace="header :: header ('home',${guild_name}, ${isAdmin})">...</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="section no-pad-bot main" id="index-banner">
|
||||||
|
|
||||||
|
<div class="center row ">
|
||||||
|
<div class="row center valign-wrapper ">
|
||||||
|
<div class="col l6 m12 s12">
|
||||||
|
<h2 class="red-text text-darken-2" style="font-weight: 1000">STOP !</h2>
|
||||||
|
<h3 class=" blue-grey-text "><b>Who are you ??? Why are you here ???</b></h3>
|
||||||
|
|
||||||
|
|
||||||
|
<a class="btn btn-large light-green darken-3 waves-effect" href="/">
|
||||||
|
<i class="large material-icons">home</i>
|
||||||
|
</a>
|
||||||
|
<h6 class=" blue-grey-text ">403 – Forbidden</h6>
|
||||||
|
</div>
|
||||||
|
<div class="col l6 m12 s12">
|
||||||
|
<img class="" src="/img/403.gif" style="border:none;outline: none"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/navabar.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script th:src="@{/js/fontawesome.js}"></script>
|
||||||
|
<script th:src="@{/js/workerRegister.js}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
72
src/main/resources/templates/error/404.html
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Claptrap Bot</title>
|
||||||
|
<link href="/favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="/css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/manifest.json" rel="manifest"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div th:replace="header :: header ('home',${guild_name}, ${isAdmin})">...</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="section no-pad-bot main" id="index-banner">
|
||||||
|
|
||||||
|
<div class="center row">
|
||||||
|
<div class="row center">
|
||||||
|
<div class="col l6 m12 s12">
|
||||||
|
<h2 class="red-text text-darken-2" style="font-weight: 1000">Oops !</h2>
|
||||||
|
<h3 class=" blue-grey-text "><b>You are lost !</b></h3>
|
||||||
|
<h3 class=" blue-grey-text "><b>Page not found !</b></h3>
|
||||||
|
<a class="btn btn-large light-green darken-3 waves-effect" href="/">
|
||||||
|
<i class="large material-icons">home</i>
|
||||||
|
</a>
|
||||||
|
<h6 class=" blue-grey-text ">404 – Not Found</h6>
|
||||||
|
</div>
|
||||||
|
<div class="col l6 m12 s12">
|
||||||
|
<img class="" src="/img/404.gif" style="border:none;outline: none"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/navabar.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script th:src="@{/js/fontawesome.js}"></script>
|
||||||
|
<script th:src="@{/js/workerRegister.js}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
91
src/main/resources/templates/error/500.html
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Claptrap Bot</title>
|
||||||
|
<link href="/favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/manifest.json" rel="manifest"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
<style>
|
||||||
|
@media only screen and (max-width: 992px) {
|
||||||
|
.row.valign-wrapper {
|
||||||
|
display: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 992px) {
|
||||||
|
img {
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div th:replace="header :: header ('home',${guild_name}, ${isAdmin})">...</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="section no-pad-bot main" id="index-banner">
|
||||||
|
|
||||||
|
<div class="center row ">
|
||||||
|
<div class="row center valign-wrapper ">
|
||||||
|
<div class="col l6 m12 s12">
|
||||||
|
<h2 class="red-text text-darken-2 " style="font-weight: 1000">Well...</h2>
|
||||||
|
<h3 class=" blue-grey-text ">Something was wrong with the server... </h3>
|
||||||
|
<h2 class=" blue-grey-text "><i class="fas fa-grin-beam-sweat"></i></h2>
|
||||||
|
|
||||||
|
<a class="btn btn-large light-green darken-3 waves-effect" href="/">
|
||||||
|
<i class="large material-icons">home</i>
|
||||||
|
</a>
|
||||||
|
<h6 class=" blue-grey-text ">500 – Internal Server Error</h6>
|
||||||
|
</div>
|
||||||
|
<div class="col l6 m12 s12">
|
||||||
|
<img class="" src="/img/500.gif" style="border:none;outline: none"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/navabar.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script th:src="@{/js/fontawesome.js}"></script>
|
||||||
|
<script th:src="@{/js/workerRegister.js}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
27
src/main/resources/templates/footer.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<link href="../static/css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="footer-copyright brown darken-4" th:fragment="footer">
|
||||||
|
<div class="container center-align">
|
||||||
|
<a class="" href="https://github.com/Sebclem/ClaptrapBot" style="margin-right: 10px; height: 41px"
|
||||||
|
target="_blank">
|
||||||
|
<img alt="Github" height="41px" th:src="@{/img/GitHub.png}"/>
|
||||||
|
<img alt="Github" height="41px" style="margin-left: -3px" th:src="@{/img/GitHub_Logo.png}"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://www.buymeacoffee.com/seb6596" target="_blank">
|
||||||
|
<img alt="Buy Me A Coffee"
|
||||||
|
src="https://www.buymeacoffee.com/assets/img/guidelines/download-assets-sm-2.svg"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
194
src/main/resources/templates/header.html
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
<!-- NAV BAR -->
|
||||||
|
<!-- AND -->
|
||||||
|
<!-- LOGIN -->
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
<link href="../static/css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
|
||||||
|
<div th:fragment="header (page, guild_name, isAdmin)">
|
||||||
|
<nav class="brown darken-4 z-depth-3" role="navigation">
|
||||||
|
<div class="nav-wrapper container">
|
||||||
|
<a class="brand-logo hide-on-small-and-down" href="/" style="white-space: nowrap">Claptrap Bot</a>
|
||||||
|
<a class="brand-logo hide-on-med-and-up show-on-small" href="/" style="white-space: nowrap">Claptrap</a>
|
||||||
|
<ul class="right hide-on-med-and-down">
|
||||||
|
<li>
|
||||||
|
|
||||||
|
<a class="truncate waves-effect brown darken-3 waves-light btn-flat grey-text text-darken-1 dropdown-trigger"
|
||||||
|
data-target="dropdown_guilds"
|
||||||
|
id="drop-trigger-guilds" style="margin-top: 2px;margin-right: 10px;" th:if="${guild_name != ''}"
|
||||||
|
th:inline="text">[[${guild_name}]]<img class="brand-logo left circle"
|
||||||
|
id="guildLogo"
|
||||||
|
style="max-height: 100%; margin-right: 10px; padding: 2px; padding-left: 0"
|
||||||
|
th:src="${guild_icon}"/></a>
|
||||||
|
</li>
|
||||||
|
<li class="" th:classappend="(${page} == 'home')? 'active' : ''">
|
||||||
|
<a class="waves-effect waves-light" href="/">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="disable" th:classappend="(${page} == 'music')? 'active' : ''">
|
||||||
|
<a class="waves-effect waves-light" href="/music">Music Control</a>
|
||||||
|
</li>
|
||||||
|
<li class="disable" th:classappend="(${page} == 'rank')? 'active' : ''">
|
||||||
|
<a class="waves-effect waves-light" href="/rank">Stats</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="nav-bar-account">
|
||||||
|
<a class="dropdown-account dropdown-trigger" data-target="dropdown_connected"><i
|
||||||
|
class="material-icons">account_box</i></a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<a class="sidenav-trigger" data-target="nav-mobile" href="#"><i class="material-icons">menu</i></a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<ul class="sidenav" id="nav-mobile">
|
||||||
|
<li class="center">
|
||||||
|
<a class="brand-logo" href="/" style="font-weight: bold"><h3 class="blue-grey-text text-darken-4"
|
||||||
|
style="font-weight: bold">Claptrap</h3></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="divider"></div>
|
||||||
|
</li>
|
||||||
|
<li class="center ">
|
||||||
|
<a class="nav-change-guild truncate waves-effect waves-light btn grey lighten-2 black-text "
|
||||||
|
style="" th:text="${guild_name}"></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="divider"></div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="center" th:classappend="(${page} == 'home')? 'active' : ''">
|
||||||
|
<a class="waves-effect waves-light sidenav-trigger" data-target="slide-out" href="/">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="center" th:classappend="(${page} == 'music')? 'active' : ''">
|
||||||
|
<a class="waves-effect waves-light" href="/music">Music Control</a>
|
||||||
|
</li>
|
||||||
|
<li class="center" th:classappend="(${page} == 'rank')? 'active' : ''">
|
||||||
|
<a class="waves-effect waves-light" href="/rank">Stats</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<div class="divider"></div>
|
||||||
|
</li>
|
||||||
|
<li><a class="center nav-change-guild" href="#">Change Server</a></li>
|
||||||
|
<li class="center bot-settings" th:classappend="(${page} == 'settings')? 'active' : ''"
|
||||||
|
th:style="${isAdmin} ? '' : 'visibility: hidden; display: none;'">
|
||||||
|
<a class="waves-effect waves-light" href="/settings">Bot Settings</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="center tooltipped" data-delay="50" data-position="bottom" data-tooltip="Under Development!">My
|
||||||
|
Account</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="center tooltipped" data-delay="50" data-position="bottom" data-tooltip="Under Development!">My
|
||||||
|
Playlists</a>
|
||||||
|
</li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
|
||||||
|
<li><a class="center red-text nav-disconnect" href="#" style="font-weight: bold">Disconnect</a></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<ul class="dropdown-content" id="dropdown_guilds">
|
||||||
|
<!--/*@thymesVar id="mutual_guilds" type="java.util.List<net.dv8tion.jda.core.entities.Guild>"*/-->
|
||||||
|
<th:block th:each="guild : ${mutual_guilds}">
|
||||||
|
<li class="guild_change" style="height: 50px; white-space: nowrap;"
|
||||||
|
th:attr="data-id = ${guild.getId()}" th:if="${guild.getId() != guild_id}">
|
||||||
|
<img class="left circle"
|
||||||
|
style="max-height: 100%; padding: 5px; " th:src="${guild.getIconUrl() == null ? 'https://discordapp.com/assets/dd4dbc0016779df1378e7812eabaa04d.png' : guild.getIconUrl()}"/><a
|
||||||
|
class="center blue-grey-text text-darken-4" style="margin-left: 50px" th:inline="text">[[${guild.getName()}]]</a>
|
||||||
|
</li>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Dropdown connected -->
|
||||||
|
<ul class="dropdown-content " id="dropdown_connected">
|
||||||
|
<li>
|
||||||
|
<a class="center blue-grey-text text-darken-4 tooltipped" data-delay="50" data-position="left"
|
||||||
|
data-tooltip="It's you !" id="nav-name" style="font-weight: bold"></a>
|
||||||
|
</li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li><a class="center nav-change-guild" href="#">Change Server</a></li>
|
||||||
|
<li class="bot-settings" th:style="${isAdmin} ? '' : 'visibility: hidden; display: none;'">
|
||||||
|
<a class=" center waves-effect waves-light " href="/settings">Bot Settings</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="center tooltipped" data-delay="50" data-position="left" data-tooltip="Under Development!">My
|
||||||
|
Account</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="center tooltipped" data-delay="50" data-position="left" data-tooltip="Under Development!">My
|
||||||
|
Playlists</a>
|
||||||
|
</li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
|
||||||
|
<li><a class="center red-text nav-disconnect" style="font-weight: bold">Disconnect</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<!--________________________________________-->
|
||||||
|
<!-- Guild modal -->
|
||||||
|
<!--________________________________________-->
|
||||||
|
|
||||||
|
<div class="modal" id="modal_guild">
|
||||||
|
<div class="modal-content" style="padding-bottom: 0px">
|
||||||
|
<div class="row" style="margin-bottom: 0px">
|
||||||
|
<h3 class="col l12 m12 s12 center">Server Selection</h3>
|
||||||
|
<div class="col l4 offset-l4 m8 offset-m4 offset-s3 s8 center">
|
||||||
|
<form action="#" class="left-align" id="guild_form">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a class="modal-action modal-close waves-effect waves-green btn-flat disabled" href="#"
|
||||||
|
id="btn_ok_guild">Ok</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal" id="modal_internet">
|
||||||
|
<div class="modal-content" style="padding-bottom: 0px">
|
||||||
|
<div class="row" style="margin-bottom: 0px">
|
||||||
|
<h3 class="col l12 m 12 s12 center red-text">Can't connect to the server!</h3>
|
||||||
|
<div class="col l6 offset-l3 offset-m1 m10 offset-s1 s10 center">
|
||||||
|
<p> Please check your connection and reload the app!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="" id="radioTemplateGuild" style="visibility: hidden; display: none ">
|
||||||
|
<label>
|
||||||
|
<input class="with-gap" data-icon="@url" id="@id" name="guildRadio" type="radio" value="@id"/>
|
||||||
|
<span><img class="circle left" src="@url" style="max-height: 100%; margin-right: 6px"/> @name</span>
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
<!-- -->
|
||||||
|
<!-- END -->
|
||||||
|
<!-- -->
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
154
src/main/resources/templates/index.html
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-144247946-1"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-144247946-1');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<meta content="Claptrap discord bot at your service! Add me to your discord server and my beautiful web interface will be there for you ! Music control, config, news, you can do anything with my web page!"
|
||||||
|
name="description"/>
|
||||||
|
<title>Claptrap Bot</title>
|
||||||
|
<link href="/favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/manifest.json" rel="manifest"/>
|
||||||
|
|
||||||
|
<th:block th:if="${isLogged} == true and ${noMutualGuilds} == false">
|
||||||
|
<link href="//cdnjs.cloudflare.com/ajax/libs/octicons/2.0.2/octicons.min.css" rel="stylesheet"/>
|
||||||
|
<link href="css/github-activity.css" rel="stylesheet"/>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
<style>
|
||||||
|
@media only screen and (max-width: 992px) {
|
||||||
|
.row.valign-wrapper {
|
||||||
|
display: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
<header>
|
||||||
|
<div th:replace="header :: header ('home',${guild_name}, ${isAdmin})">...</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col offset-l4 l4 m6 offset-m3 s12">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section no-pad-bot container main" id="index-banner">
|
||||||
|
<div th:if="${isLogged} == false">
|
||||||
|
<div class="row valign-wrapper">
|
||||||
|
<div class="col m6 offset-s2 s8 center">
|
||||||
|
<img class="responsive-img" src="/favicon.png"/>
|
||||||
|
<div class="card blue-grey">
|
||||||
|
<div class="card-content white-text center z-depth-5">
|
||||||
|
<span class="card-title">Add me to your server !</span>
|
||||||
|
<a class="btn green" target="_blank" th:href="${inviteLink}">Invite me !</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col m6 s12 center flow-text">
|
||||||
|
<h2>Hello you !</h2>
|
||||||
|
<h4>Please log in to have access to your server</h4>
|
||||||
|
<a class="btn green pulse" href="/login" style="margin-top: 10px">Log in / Register</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div th:if="${isLogged} == true">
|
||||||
|
<div th:if="${noMutualGuilds} == true">
|
||||||
|
<div class="row valign-wrapper">
|
||||||
|
<div class="col m6 offset-s3 s6">
|
||||||
|
<img class="responsive-img" src="/favicon.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="col m6 s12 center flow-text">
|
||||||
|
<h2>Oh no !</h2>
|
||||||
|
<h4>We don't have any mutual server !</h4>
|
||||||
|
<h5>You can change this by inviting me with this button !</h5>
|
||||||
|
<a class="btn blue pulse" href="/login" style="margin-top: 10px" target="_blank"
|
||||||
|
th:href="${inviteLink}">Invite me !</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:if="${noMutualGuilds} == false">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col l6 offset-s2 s8 center">
|
||||||
|
<img class="responsive-img" src="/favicon.png"/>
|
||||||
|
<h2 class="flow-text">Home Page Comming soon!</h2>
|
||||||
|
<div class="card blue-grey">
|
||||||
|
<div class="card-content white-text center z-depth-4">
|
||||||
|
<span class="card-title">Add me to your server !</span>
|
||||||
|
<a class="btn green waves-effect" target="_blank" th:href="${inviteLink}">Invite me
|
||||||
|
!</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col l6 xl5 offset-xl1 s12">
|
||||||
|
<div class="z-depth-2" id="feed" style="height: 80vh; box-sizing: content-box"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/navabar.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script th:src="@{/js/fontawesome.js}"></script>
|
||||||
|
<script th:src="@{/js/workerRegister.js}"></script>
|
||||||
|
<th:block th:if="${isLogged} == true and ${noMutualGuilds} == false">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.0.1/mustache.min.js"
|
||||||
|
type="text/javascript"></script>
|
||||||
|
<script th:src="@{/js/github-activity.js}"></script>
|
||||||
|
<script>
|
||||||
|
GitHubActivity.feed({
|
||||||
|
username: "Sebclem",
|
||||||
|
repository: "ClaptrapBot", // optional
|
||||||
|
selector: "#feed",
|
||||||
|
limit: 20 // optional
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
80
src/main/resources/templates/loading.html
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Claptrap Bot</title>
|
||||||
|
<link href="/favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
<!-- NAV BAR -->
|
||||||
|
<!-- AND -->
|
||||||
|
<!-- LOGIN -->
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
<header>
|
||||||
|
<nav class="brown darken-4 z-depth-3" role="navigation">
|
||||||
|
<div class="nav-wrapper container">
|
||||||
|
<a class="brand-logo hide-on-small-and-down center" href="/" style="white-space: nowrap">Claptrap Bot</a>
|
||||||
|
<a class="brand-logo hide-on-med-and-up show-on-small center" href="/"
|
||||||
|
style="white-space: nowrap">Claptrap</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
<!-- -->
|
||||||
|
<!-- END -->
|
||||||
|
<!-- -->
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="section no-pad-bot main" id="index-banner">
|
||||||
|
<div class="row center center-align">
|
||||||
|
<h3 class="">Bot is starting</h3>
|
||||||
|
</div>
|
||||||
|
<div class="row center">
|
||||||
|
<div class="preloader-wrapper big active">
|
||||||
|
<div class="spinner-layer spinner-blue-only">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row center center-align">
|
||||||
|
<h3>Please wait</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/loading.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
129
src/main/resources/templates/login.html
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-144247946-1"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-144247946-1');
|
||||||
|
</script>
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Claptrap Bot</title>
|
||||||
|
<link href="/favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-4">
|
||||||
|
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
<!-- NAV BAR -->
|
||||||
|
<!-- AND -->
|
||||||
|
<!-- LOGIN -->
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
<header>
|
||||||
|
<nav class="brown darken-4 z-depth-3" role="navigation">
|
||||||
|
<div class="nav-wrapper container">
|
||||||
|
<a class="brand-logo hide-on-small-and-down center" href="/" style="white-space: nowrap">Claptrap Bot</a>
|
||||||
|
<a class="brand-logo hide-on-med-and-up show-on-small center" href="/"
|
||||||
|
style="white-space: nowrap">Claptrap</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
<!-- -->
|
||||||
|
<!-- END -->
|
||||||
|
<!-- -->
|
||||||
|
<!--__________________________________________________________-->
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="section main" id="index-banner">
|
||||||
|
<div class="row">
|
||||||
|
<div class="card-panel col xl8 offset-xl2 l10 offset-l1 m10 offset-m1 s10 offset-s1">
|
||||||
|
<div class="row center">
|
||||||
|
<div class="col s12">
|
||||||
|
<h3 class="" style="font-weight: bold">Sign in</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row center">
|
||||||
|
<a class="btn waves-effect waves-light" style="background-color: #7289DA" th:href="${redirect_url}">
|
||||||
|
Sign in with discord <i class="fab fa-discord fa-lg" style="margin-left: 2px"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="row center">
|
||||||
|
<div class="col s12">
|
||||||
|
<h3 style="font-weight: bold">Or</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row center" style="margin-bottom: 0px">
|
||||||
|
<form id="login_form" name="login_form">
|
||||||
|
<div class="row" style="margin-bottom: 0px">
|
||||||
|
<div class="input-field col l6 offset-l3 m10 offset-m1 s10 offset-s1">
|
||||||
|
<i class="material-icons prefix">account_box</i>
|
||||||
|
<input autocomplete="username" class="validate" id="user_input" name="username"
|
||||||
|
type="text"/>
|
||||||
|
<label for="user_input">User Name</label>
|
||||||
|
<span class="helper-text" data-error="User not registered!"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col l6 offset-l3 m10 offset-m1 s10 offset-s1">
|
||||||
|
<i class="material-icons prefix">security</i>
|
||||||
|
<input autocomplete="current-password" class="validate" id="password_input" name="password"
|
||||||
|
type="password"/>
|
||||||
|
<label for="password_input">Password</label>
|
||||||
|
<span class="helper-text" data-error="Wrong password!"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-bottom: 10px">
|
||||||
|
<button class="btn waves-effect waves-light light-green darken-1 scale-transition scale-out"
|
||||||
|
id="btn-submit-connect"
|
||||||
|
name="action" type="submit">
|
||||||
|
Submit<i class="material-icons right">send</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<a class="btn waves-effect waves-light brown" href="/register">
|
||||||
|
Create account<i class="material-icons right">person_add</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/login.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script crossorigin="anonymous" src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
440
src/main/resources/templates/music.html
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-144247946-1"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-144247946-1');
|
||||||
|
</script>
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Music Control - Claptrap Bot</title>
|
||||||
|
<link href="favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="/css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/manifest.json" rel="manifest"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
<style>
|
||||||
|
@media only screen and (max-width: 1200px) {
|
||||||
|
#modalAdd {
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 1200px) {
|
||||||
|
#modalAdd {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 993px) {
|
||||||
|
#card-playlist {
|
||||||
|
max-height: 75vh;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#card-playlist {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#card-playlist li:not(.active) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modalAdd {
|
||||||
|
height: 85% !important;
|
||||||
|
max-height: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar > img {
|
||||||
|
position: absolute;
|
||||||
|
width: 80px;
|
||||||
|
height: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
left: 15px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collection-item.avatar {
|
||||||
|
padding-left: 105px !important;
|
||||||
|
padding-right: 75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll::-webkit-scrollbar-thumb {
|
||||||
|
background: #666;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll::-webkit-scrollbar-track {
|
||||||
|
background: #ddd;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
|
||||||
|
<!--/*@thymesVar id="guild_name" type="java.lang.String"*/-->
|
||||||
|
<!--/*@thymesVar id="redirect_url" type="java.lang.String"*/-->
|
||||||
|
<!--/*@thymesVar id="isAdmin" type="java.lang.Boolean"*/-->
|
||||||
|
<header>
|
||||||
|
<div th:replace="header :: header ('music',${guild_name}, ${isAdmin})">...</div>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<div class="section no-pad-bot main" id="index-banner">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col l8 s12 m12">
|
||||||
|
<div class="row center">
|
||||||
|
<img class="responsive-img z-depth-3" id="music_img" src="/img/disconnected.png"
|
||||||
|
style="max-width: 30%"/>
|
||||||
|
</div>
|
||||||
|
<h4 class="center" id="music_text"></h4>
|
||||||
|
<div class="row center" style="margin-bottom: 0px">
|
||||||
|
<div class="progress col l6 offset-l3 m10 offset-m1 s10 offset-s1 z-depth-3">
|
||||||
|
<div class="determinate" id="music_progress" style="width: 0%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row center">
|
||||||
|
<div class="col l2 offset-l3 m2 offset-m1 s2 offset-s1 left-align" id="current_time"
|
||||||
|
style="padding: 0px">0:00
|
||||||
|
</div>
|
||||||
|
<div class="col l2 offset-l2 m2 offset-m6 s2 offset-s6 right-align " id="total_time"
|
||||||
|
style="padding: 0px">0:00
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row center">
|
||||||
|
<div class="col l2 offset-l3 m4 s4 center">
|
||||||
|
<a class="btn-large red darken-4 z-depth-3 waves-effect waves-light ctl-btn" id="btn_stop">
|
||||||
|
<i class="material-icons medium">stop</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col l2 m4 s4 center">
|
||||||
|
<a class="btn-large green darken-4 z-depth-3 waves-effect waves-light ctl-btn" id="btn_play">
|
||||||
|
<i class="material-icons medium">play_arrow</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col l2 m4 s4 center">
|
||||||
|
<a class="btn-large light-blue darken-4 z-depth-3 waves-effect waves-light ctl-btn"
|
||||||
|
id="btn_next">
|
||||||
|
<i class="material-icons">skip_next</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row center">
|
||||||
|
|
||||||
|
<div class="col offset-l5 l2 m2 offset-m5 s2 offset-s5 center">
|
||||||
|
<a class="btn black z-depth-3 waves-effect waves-light modal-trigger" href="#modal_current_info"
|
||||||
|
id="btn_info">
|
||||||
|
<i class="material-icons">info</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row center">
|
||||||
|
<div class="col offset-l5 l2 m4 offset-m4 s4 offset-s4 center">
|
||||||
|
<a class="btn-large red accent-4 z-depth-3 waves-effect waves-light ctl-btn"
|
||||||
|
id="btn_disconnect">
|
||||||
|
<i class="material-icons">call_end</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col l4 m12 s12">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="padding: 0px;">
|
||||||
|
<div class="row center valign-wrapper" style="margin: 0px">
|
||||||
|
<div class="col l3 m5 s5 center blue-grey-text text-darken-3"><h5><b>Playlist</b></h5>
|
||||||
|
</div>
|
||||||
|
<div class="col l3 m2 s2 center" style="padding-right: 0px; padding-left: 0px">
|
||||||
|
<a class="waves-effect waves-light btn modal-trigger red darken-4 ctl-btn"
|
||||||
|
id="flush_btn"><i class="material-icons">delete_sweep</i></a>
|
||||||
|
</div>
|
||||||
|
<div class="col l3 m2 s2 center" style="padding-right: 0px; padding-left: 0px">
|
||||||
|
<!-- Modal Trigger -->
|
||||||
|
<a class="waves-effect waves-light btn modal-trigger green darken-4" href="#modalAdd"
|
||||||
|
id="add_btn"><i class="material-icons">add_circle_outline</i></a>
|
||||||
|
</div>
|
||||||
|
<div class="col l3 m2 s2 center " style="padding-left: 0px">
|
||||||
|
<div class="row switch blue-grey-text text-darken-3" style="margin-bottom: 0px">
|
||||||
|
AutoFlow
|
||||||
|
</div>
|
||||||
|
<div class="row switch tooltipped ctl-btn" data-delay="50" data-position="bottom"
|
||||||
|
data-tooltip="Experimental!">
|
||||||
|
<label>
|
||||||
|
<input id="autoflow" type="checkbox"/>
|
||||||
|
<span class="lever"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="row card-panel scroll" id="card-playlist">
|
||||||
|
<div class="col s12" style="padding: 0">
|
||||||
|
<ul class="collapsible" data-collapsible="accordion" id="playlist_list"
|
||||||
|
style="margin: 0px">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Music -->
|
||||||
|
<div class="modal bottom-sheet" id="modal_current_info">
|
||||||
|
<div class="modal-content">
|
||||||
|
<ul class="collection">
|
||||||
|
<li class="collection-item " id="modal_title"></li>
|
||||||
|
<li class="collection-item " id="modal_author"></li>
|
||||||
|
<li class="collection-item " id="modal_lenght"></li>
|
||||||
|
<li class="collection-item " id="modal_url"></li>
|
||||||
|
<li class="collection-item " id="modal_submit"></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--Add Modal-->
|
||||||
|
<div class="modal modal-fixed-footer " id="modalAdd">
|
||||||
|
<div class="modal-content" style="padding-bottom: 0px">
|
||||||
|
<div class="row valign-wrapper">
|
||||||
|
<h3 class="col l12 m12 s12 center"> Add Music</h3>
|
||||||
|
</div>
|
||||||
|
<div class="row" id="musicSearch" style="margin-bottom: 0px">
|
||||||
|
<div class="row">
|
||||||
|
<form class="col l12 m12 s12">
|
||||||
|
<div class="row" style="margin-bottom: 0">
|
||||||
|
<div class="input-field col offset-l1 l9 m9 s7"
|
||||||
|
style="padding-left: 0px; padding-right: 0px">
|
||||||
|
<!--<i class="material-icons prefix">link</i>-->
|
||||||
|
<input class="validate" id="input_search" type="text"/>
|
||||||
|
<label for="input_search">Search</label>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col l1 m2 s3" style="margin-top: 22px">
|
||||||
|
<button class="btn waves-effect waves-light green darken-4 white-text" id="btn_search"
|
||||||
|
type="button"><i class="material-icons">search</i></button>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="col l1 m1 s2 center" style="padding: 0; margin-top: 15px;">-->
|
||||||
|
<!-- <div class="row switch blue-grey-text text-darken-3" style="margin-bottom: 0px">-->
|
||||||
|
<!-- Playlist-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- <div class="row switch">-->
|
||||||
|
<!-- <label>-->
|
||||||
|
<!-- <input type="checkbox" id="playlistSearch"/>-->
|
||||||
|
<!-- <span class="lever"></span>-->
|
||||||
|
<!-- </label>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m12 l12 center scale-transition scale-out hide" id="search_load"
|
||||||
|
style="margin-top: 25px">
|
||||||
|
<div class="preloader-wrapper big active">
|
||||||
|
<div class="spinner-layer spinner-blue-only">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="collection col l12 m12 s12 scale-transition scale-out" id="search_result"
|
||||||
|
style="padding: 0">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<span style="margin-right: 10px">
|
||||||
|
<label>
|
||||||
|
<input checked="checked" id="bottom" name="group1" type="radio"/>
|
||||||
|
<span>Bottom</span>
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
|
<span style="margin-right: 10px">
|
||||||
|
<label>
|
||||||
|
<input name="group1" type="radio"/>
|
||||||
|
<span>Top</span>
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
|
<a class="modal-action modal-close waves-effect waves-green btn-flat" href="#">Close</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Playlist template-->
|
||||||
|
<li id="playlist_template" style="visibility: hidden; display: none">
|
||||||
|
<div class="collapsible-header"><i class="material-icons">drag_handle</i>@title</div>
|
||||||
|
<div class="collapsible-body">
|
||||||
|
<ul class="collection">
|
||||||
|
<li class="collection-item">Author: @author</li>
|
||||||
|
<li class="collection-item">Duration: @lenght</li>
|
||||||
|
<li class="collection-item">URL: <a href="@url" target="_blank">@url</a></li>
|
||||||
|
<li class="collection-item">Submitted by: @user</li>
|
||||||
|
<li class="collection-item center">
|
||||||
|
<a class="btn red darken-4 z-depth-3 waves-effect waves-light btn_dell_playlist" data_url="@url">
|
||||||
|
<i class="material-icons medium">delete</i>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- Modal Chanels -->
|
||||||
|
<div class="modal" id="modalChanels">
|
||||||
|
<div class="modal-content" style="padding-bottom: 0px">
|
||||||
|
<div class="row" style="margin-bottom: 0px">
|
||||||
|
<h3 class="col l12 m12 s12 center">Vocal Channels</h3>
|
||||||
|
<div class="col offset-l4 l4 m4 offset-m4 s8 offset-s2 center">
|
||||||
|
<form action="#" class="left-align" id="channelForm">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a class="modal-action modal-close waves-effect waves-red btn-flat " href="/">Cancel</a>
|
||||||
|
<a class="modal-action modal-close waves-effect waves-green btn-flat disabled" href="#!"
|
||||||
|
id="btn_ok_channel">Connect</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Loading Modal-->
|
||||||
|
<div class="modal valign-wrapper" id="modal_loading">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="row center">
|
||||||
|
<h3 class="col l12 m12 s12 center">Please wait</h3>
|
||||||
|
</div>
|
||||||
|
<div class="row center">
|
||||||
|
<div class="preloader-wrapper big active">
|
||||||
|
<div class="spinner-layer spinner-blue">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spinner-layer spinner-red">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spinner-layer spinner-yellow">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spinner-layer spinner-green">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="" id="radioTemplate" style="visibility: hidden; display: none">
|
||||||
|
<label>
|
||||||
|
<input class="with-gap" id="@id" name="vocalRadio" type="radio" value="@id"/>
|
||||||
|
<span for="@id">@name</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/music.js}"></script>
|
||||||
|
<script th:src="@{/js/navabar.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script th:src="@{/js/workerRegister.js}"></script>
|
||||||
|
<script th:src="@{/js/fontawesome.js}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
66
src/main/resources/templates/oauthCallback.html
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Claptrap Bot</title>
|
||||||
|
<link href="/favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div th:replace="header :: header ('home',${guild_name}, ${isAdmin})">...</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="section no-pad-bot main" id="index-banner">
|
||||||
|
<div class="row center">
|
||||||
|
<div class="preloader-wrapper big active">
|
||||||
|
<div class="spinner-layer spinner-blue-only">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row center center-align">
|
||||||
|
<h3>Please wait</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
<script th:src="@{/js/oauthCallback.js}"></script>
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/navabar.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script th:src="@{/js/fontawesome.js}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
298
src/main/resources/templates/rank.html
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-144247946-1"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-144247946-1');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Claptrap Bot</title>
|
||||||
|
<link href="/favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/manifest.json" rel="manifest"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
<style>
|
||||||
|
tr {
|
||||||
|
border-color: #fbcf40;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 span {
|
||||||
|
color: #fbcf40;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
td span {
|
||||||
|
color: #fbcf40;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible {
|
||||||
|
border-color: #fbcf40;
|
||||||
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsible-header {
|
||||||
|
border-color: #fbcf40;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
|
||||||
|
<!--/*@thymesVar id="guild_name" type="java.lang.String"*/-->
|
||||||
|
<!--/*@thymesVar id="redirect_url" type="java.lang.String"*/-->
|
||||||
|
<!--/*@thymesVar id="isAdmin" type="java.lang.Boolean"*/-->
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div th:replace="header :: header ('rank',${guild_name}, ${isAdmin})">...</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<!--/*@thymesVar id="stack" type="net.Broken.Tools.UserManager.Stats.GuildStatsPack"*/-->
|
||||||
|
<th:block th:if="${stack != null}">
|
||||||
|
<div class="row" style="margin-bottom: 0">
|
||||||
|
<div class="col l6 offset-l3 m10 offset-m1 s10 offset-s1 card-panel grey darken-4 white-text">
|
||||||
|
<h4 class="center" style="font-weight: bold"><span th:remove="tag" th:text="${guild_name}"></span><br/>Stats
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="card-panel col l6 offset-l3 m10 offset-m1 s10 offset-s1 grey darken-4 white-text">
|
||||||
|
<div class="row" style="margin-bottom: 0">
|
||||||
|
<div class="col s12 center" style="margin-top: 10px">
|
||||||
|
<img class="circle" style="border-color: green; border-style: solid;"
|
||||||
|
th:src="${stack.selfStats.avatarUrl}"/>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 center">
|
||||||
|
<h4 style="font-weight: bold; margin: 0;" th:text="${stack.selfStats.userName}"></h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-bottom: 0">
|
||||||
|
<div class="col m6 s12 center">
|
||||||
|
<table class="centered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Rank</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h4 style="font-weight: bold; margin: 0"><span th:remove="tag"
|
||||||
|
th:text="${stack.rank}"></span> <span
|
||||||
|
th:text="${' / ' + stack.ranking.size()}">/ 50</span></h4>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col m6 s12 center">
|
||||||
|
<table class="centered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Experience</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h4 style="font-weight: bold; margin: 0"><span th:remove="tag"
|
||||||
|
th:text="${stack.selfStats.total}"></span>
|
||||||
|
<span>Xp</span>
|
||||||
|
</h4>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m6 s12 center">
|
||||||
|
<table class="centered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Vocal Time</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h4 style="font-weight: bold; margin: 0">
|
||||||
|
<span th:remove="tag"
|
||||||
|
th:text="${T(net.Broken.Tools.TimeConvertor).sToTime(stack.selfStats.voiceTime).get(0)}"></span> <span>H</span>
|
||||||
|
<span th:remove="tag"
|
||||||
|
th:text="${T(net.Broken.Tools.TimeConvertor).sToTime(stack.selfStats.voiceTime).get(1)}"></span> <span>M</span>
|
||||||
|
<span th:remove="tag"
|
||||||
|
th:text="${T(net.Broken.Tools.TimeConvertor).sToTime(stack.selfStats.voiceTime).get(2)}"></span> <span>S</span>
|
||||||
|
</h4>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col m6 s12 center">
|
||||||
|
<table class="centered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Message count</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h4 style="font-weight: bold; margin: 0"><span
|
||||||
|
th:remove="tag"
|
||||||
|
th:text="${stack.selfStats.messageCount}"></span> <span>msg</span>
|
||||||
|
</h4>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col l6 offset-l3 m10 offset-m1 hide-on-small-and-down card-panel grey darken-4 white-text">
|
||||||
|
<h3 class="center"><b>Ranking</b></h3>
|
||||||
|
|
||||||
|
<table class="centered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Rank</th>
|
||||||
|
<th></th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Vocal Time</th>
|
||||||
|
<th>Message Count</th>
|
||||||
|
<th>Total XP</th>
|
||||||
|
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<th:block th:each="stat : ${stack.ranking}">
|
||||||
|
<tr>
|
||||||
|
<td th:text="${stat.rank}"></td>
|
||||||
|
<td><img class="circle" style="max-height: 50px" th:src="${stat.avatarUrl}"/></td>
|
||||||
|
<td th:text="${stat.userName}"></td>
|
||||||
|
<td> <span th:remove="tag"
|
||||||
|
th:text="${T(net.Broken.Tools.TimeConvertor).sToTime(stat.voiceTime).get(0)}"></span> <span>H</span>
|
||||||
|
<span th:remove="tag"
|
||||||
|
th:text="${T(net.Broken.Tools.TimeConvertor).sToTime(stat.voiceTime).get(1)}"></span> <span>M</span>
|
||||||
|
<span th:remove="tag"
|
||||||
|
th:text="${T(net.Broken.Tools.TimeConvertor).sToTime(stat.voiceTime).get(2)}"></span> <span>S</span></td>
|
||||||
|
<td th:text="${stat.messageCount}"></td>
|
||||||
|
<td th:text="${stat.total}"></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col s10 offset-s1 hide-on-med-and-up card-panel grey darken-4 white-text">
|
||||||
|
<h3 class="center"><b>Ranking</b></h3>
|
||||||
|
|
||||||
|
<ul class="collapsible popout">
|
||||||
|
<th:block th:each="stat : ${stack.ranking}">
|
||||||
|
<li>
|
||||||
|
<div class="collapsible-header grey darken-3 valign-wrapper"><span
|
||||||
|
style="font-weight: bold" th:text="${stat.rank + '. '}"></span><img
|
||||||
|
class="circle" style="max-height: 40px; margin: 0 10px 0 10px"
|
||||||
|
th:src="${stat.avatarUrl}"/> <span
|
||||||
|
th:text="${stat.userName}"></span><span class="badge new green"
|
||||||
|
data-badge-caption="xp "
|
||||||
|
th:text="${stat.total}">4</span></div>
|
||||||
|
<div class="collapsible-body grey darken-2">
|
||||||
|
<table class="centered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
<th>Vocal Time</th>
|
||||||
|
<th>Message Count</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td> <span
|
||||||
|
th:remove="tag"
|
||||||
|
th:text="${T(net.Broken.Tools.TimeConvertor).sToTime(stat.voiceTime).get(0)}"></span> <span>H</span>
|
||||||
|
<span th:remove="tag"
|
||||||
|
th:text="${T(net.Broken.Tools.TimeConvertor).sToTime(stat.voiceTime).get(1)}"></span> <span>M</span>
|
||||||
|
<span th:remove="tag"
|
||||||
|
th:text="${T(net.Broken.Tools.TimeConvertor).sToTime(stat.voiceTime).get(2)}"></span> <span>S</span></td>
|
||||||
|
<td th:text="${stat.messageCount}"></td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/navabar.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
var elems = document.querySelectorAll('.collapsible');
|
||||||
|
var instances = M.Collapsible.init(elems);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<!--<script th:src="@{/js/rank.js}"></script>-->
|
||||||
|
|
||||||
|
<script th:src="@{/js/fontawesome.js}"></script>
|
||||||
|
<script th:src="@{/js/workerRegister.js}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
134
src/main/resources/templates/register.html
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-144247946-1"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-144247946-1');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Sign up - Claptrap Bot</title>
|
||||||
|
<link href="favicon.png" rel="icon" type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/manifest.json" rel="manifest"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<div th:replace="header :: header ('','',${isAdmin})">...</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="section no-pad-bot main" id="index-banner">
|
||||||
|
<div class="row center">
|
||||||
|
<div class="row">
|
||||||
|
<h2 class="col s12">Account Registration</h2>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-bottom: 0%">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="input-field inline">
|
||||||
|
<i class="material-icons prefix">assignment_ind</i>
|
||||||
|
<input class="validate invalid" id="name" type="text"/>
|
||||||
|
<label data-error="" data-success="" for="name">Discord Name</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-bottom: 0%">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="input-field inline">
|
||||||
|
<i class="material-icons prefix">security</i>
|
||||||
|
<input class="invalid" id="passwrd" type="password"/>
|
||||||
|
<label data-error="" data-success="" for="passwrd">Password</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-bottom: 0%">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="input-field inline">
|
||||||
|
<i class="material-icons prefix">security</i>
|
||||||
|
<input class="invalid" id="passwrd2" type="password"/>
|
||||||
|
<label data-error="" data-success="" for="passwrd2">Confirm</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12">
|
||||||
|
<a class="waves-effect waves-light btn scale-transition scale-out" id="sendBtn">Send<i
|
||||||
|
class="material-icons left">send</i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Modal Structure -->
|
||||||
|
<div class="modal" id="modalToken">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="row">
|
||||||
|
<h3 class="col s12 center"> User Validation</h3>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s10 offset-s1">
|
||||||
|
<p class="center">
|
||||||
|
A validation code has been sent by private message, please copy it below.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="row" style="margin-bottom: 0px">
|
||||||
|
<div class="input-field col s6 offset-s3">
|
||||||
|
<i class="material-icons prefix">fingerprint</i>
|
||||||
|
<input class="validate" id="input_preToken" type="text"/>
|
||||||
|
<label for="input_preToken">Verification Code</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a class="modal-action waves-effect waves-green btn scale-transition scale-out" href="#" id="preTokenSend">Send</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/register.js}"></script>
|
||||||
|
<script th:src="@{/js/navabar.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script th:src="@{/js/workerRegister.js}"></script>
|
||||||
|
<script th:src="@{/js/fontawesome.js}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<script th:inline="javascript">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
|
||||||
|
var id = [[${id}]];
|
||||||
|
console.log(id);
|
||||||
|
|
||||||
|
/*]]>*/
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
214
src/main/resources/templates/settings.html
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-144247946-1"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'UA-144247946-1');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
|
<meta content="width=device-width, initial-scale=1, maximum-scale=1.0" name="viewport"/>
|
||||||
|
<title>Bot Settings - Claptrap Bot</title>
|
||||||
|
<link href="/favicon.png"
|
||||||
|
rel="icon"
|
||||||
|
type="image/x-icon"/>
|
||||||
|
|
||||||
|
<!-- CSS -->
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
|
||||||
|
<link href="css/materialize.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="css/style.css" media="screen,projection" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/manifest.json" rel="manifest"/>
|
||||||
|
<meta content="#263238" name="theme-color"/>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="blue-grey lighten-5">
|
||||||
|
|
||||||
|
<!--/*@thymesVar id="guild_name" type="java.lang.String"*/-->
|
||||||
|
<!--/*@thymesVar id="redirect_url" type="java.lang.String"*/-->
|
||||||
|
<!--/*@thymesVar id="settings" type="java.util.ArrayList<net.Broken.RestApi.Data.Settings.GetSettingsData>"*/-->
|
||||||
|
|
||||||
|
<!--/*@thymesVar id="isAdmin" type="java.lang.Boolean"*/-->
|
||||||
|
<header>
|
||||||
|
<div th:replace="header :: header ('settings',${guild_name}, ${isAdmin})">...</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div class="section no-pad-bot main container" id="index-banner">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="card-panel col s12 m12 l10 offset-l1" style="border-radius: 10px">
|
||||||
|
<div class="row">
|
||||||
|
<h2 class="center col s12" style="margin-bottom: 0">Bot Settings</h2>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="divider col s12"></div>
|
||||||
|
<div class="divider col s12"></div>
|
||||||
|
<h4 class="center col s12" th:text="${guild_name}"></h4>
|
||||||
|
<div class="divider col s12"></div>
|
||||||
|
<div class="divider col s12"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div th:each="setting : ${settings}">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col l10 offset-l1 m10 offset-m1 s10 offset-s1">
|
||||||
|
<h5 style="font-weight: bold" th:text="${setting.name}"></h5>
|
||||||
|
<div class="switch" th:if="${setting.type.toString() == 'BOOL'}">
|
||||||
|
<label>
|
||||||
|
Off
|
||||||
|
<input class="collect-switch" th:checked="${setting.current}" th:id="${setting.id}"
|
||||||
|
type="checkbox"/>
|
||||||
|
<span class="lever"></span>
|
||||||
|
On
|
||||||
|
</label>
|
||||||
|
<div th:text="${setting.description}"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-field col l12 m12 s12 collect-select" th:id="${setting.id}"
|
||||||
|
th:if="${setting.type.toString() == 'LIST'}">
|
||||||
|
<select>
|
||||||
|
<option disabled="disabled" th:selected="${setting.current} == ' '" value="">Choose
|
||||||
|
your option
|
||||||
|
</option>
|
||||||
|
<option th:each="val : ${setting.values}" th:selected="${setting.current} == ${val.id}"
|
||||||
|
th:text="${#strings.capitalize(val.name)}"
|
||||||
|
th:value="${val.id}"></option>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
<div th:text="${setting.description}"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-field col l12 m12 s12 collect-select-multiple" th:id="${setting.id}"
|
||||||
|
th:if="${setting.type.toString() == 'SELECT_LIST'}">
|
||||||
|
<select multiple="multiple">
|
||||||
|
<option disabled="disabled" value="">Choose your option
|
||||||
|
</option>
|
||||||
|
<option th:each="val : ${setting.values}" th:selected="${val.selected} == true"
|
||||||
|
th:text="${#strings.capitalize(val.name)}"
|
||||||
|
th:value="${val.id}"></option>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
<div th:text="${setting.description}"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="input-field col l12 m12 s12 collect"
|
||||||
|
th:if="${setting.type.toString() == 'STRING'}">
|
||||||
|
<input class="validate collect-text" id="first_name"
|
||||||
|
placeholder="Use @name variable"
|
||||||
|
th:id="${setting.id}" th:value="${setting.current}" type="text"/>
|
||||||
|
<div th:text="${setting.description}"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="divider col s12"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 center">
|
||||||
|
<a class="waves-effect waves-light btn green" id="sendBtn">Save<i
|
||||||
|
class="material-icons left">save</i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal valign-wrapper" id="modal_loading">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="row center">
|
||||||
|
<h3 class="col l12 m12 s12 center">Please wait</h3>
|
||||||
|
</div>
|
||||||
|
<div class="row center">
|
||||||
|
<div class="preloader-wrapper big active">
|
||||||
|
<div class="spinner-layer spinner-blue">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spinner-layer spinner-red">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spinner-layer spinner-yellow">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spinner-layer spinner-green">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="page-footer" style="padding: 0">
|
||||||
|
<div th:replace="footer :: footer">...</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Scripts-->
|
||||||
|
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
|
||||||
|
<script th:src="@{/js/materialize.js}"></script>
|
||||||
|
<script th:src="@{/js/navabar.js}"></script>
|
||||||
|
<script th:src="@{/js/js.cookie.js}"></script>
|
||||||
|
<script th:src="@{/js/settings.js}"></script>
|
||||||
|
|
||||||
|
<script th:src="@{/js/fontawesome.js}"></script>
|
||||||
|
<script th:src="@{/js/workerRegister.js}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|