This commit is contained in:
SebClem 2022-05-17 20:56:32 +02:00
parent 92c30173cb
commit c4ed20644c
Signed by: sebclem
GPG Key ID: 5A4308F6A359EA50
75 changed files with 223 additions and 30624 deletions

View File

@ -25,22 +25,26 @@ jar {
enabled(false)
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web") {
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
}
implementation("org.springframework.boot:spring-boot-starter-log4j2")
implementation 'org.codehaus.groovy:groovy-all:3.0.8'
configurations.implementation {
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-security")
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-oauth2-client")
implementation 'org.codehaus.groovy:groovy-all:3.0.8'
implementation 'com.sedmelluq:lavaplayer:1.3.77'
implementation 'net.dv8tion:JDA:4.4.0_350'
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...)
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"))
// Use MySQL Connector-J
implementation 'mysql:mysql-connector-java'
@ -48,14 +52,10 @@ dependencies {
implementation 'org.apache.commons:commons-lang3:3.12.0'
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 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 {

View File

@ -0,0 +1,25 @@
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";
}
}

View File

@ -0,0 +1,29 @@
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));
}
}

View File

@ -0,0 +1,54 @@
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();
}
}

View File

@ -0,0 +1,16 @@
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)";
}

View File

@ -0,0 +1,31 @@
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);
// });
}
}

View File

@ -0,0 +1,12 @@
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;
}
}

View File

@ -1,12 +0,0 @@
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";
}
}

View File

@ -1,207 +0,0 @@
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 {
}
}

View File

@ -1,78 +0,0 @@
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";
}
}
}

View File

@ -1,37 +0,0 @@
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();
}
}

View File

@ -1,42 +0,0 @@
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";
}
}

View File

@ -1,22 +0,0 @@
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");
}
}

View File

@ -1,9 +0,0 @@
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

View File

@ -0,0 +1,36 @@
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'

View File

@ -38,6 +38,11 @@
<AppenderRef ref="current"/>
<AppenderRef ref="RollingFile"/>
</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">
<AppenderRef ref="Console" level="info"/>
<AppenderRef ref="RollingFile" level="info"/>

View File

@ -1,299 +0,0 @@
/*!
* 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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,43 +0,0 @@
/*.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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

View File

@ -1 +0,0 @@
google-site-verification: googlefa6384608522214e.html

View File

@ -1,6 +0,0 @@
[Dolphin]
Timestamp=2017,12,24,15,16,6
Version=4
[Settings]
HiddenFilesShown=true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

File diff suppressed because one or more lines are too long

View File

@ -1,560 +0,0 @@
/*!
* 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 &raquo;</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) + ' &raquo;</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'];

File diff suppressed because one or more lines are too long

View File

@ -1,169 +0,0 @@
/*!
* 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 () {
});
}));

View File

@ -1,18 +0,0 @@
$(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");
});
}

View File

@ -1,85 +0,0 @@
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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,632 +0,0 @@
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 "&#x1F534 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");
}
}

View File

@ -1,198 +0,0 @@
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);
});
}

View File

@ -1,31 +0,0 @@
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 = "/";
}

View File

@ -1,164 +0,0 @@
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);
});
});
});

View File

@ -1,80 +0,0 @@
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'
});
});
})
});

View File

@ -1,11 +0,0 @@
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);
});
});
}

View File

@ -1,20 +0,0 @@
{
"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"
}

View File

@ -1,32 +0,0 @@
<?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>

View File

@ -1,86 +0,0 @@
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));
});
});
}
}
});

View File

@ -1,10 +0,0 @@
<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>

View File

@ -1,92 +0,0 @@
<!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>

View File

@ -1,72 +0,0 @@
<!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>

View File

@ -1,91 +0,0 @@
<!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>

View File

@ -1,27 +0,0 @@
<!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>

View File

@ -1,194 +0,0 @@
<!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>

View File

@ -1,154 +0,0 @@
<!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>

View File

@ -1,80 +0,0 @@
<!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>

View File

@ -1,129 +0,0 @@
<!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>

View File

@ -1,440 +0,0 @@
<!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>

View File

@ -1,66 +0,0 @@
<!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>

View File

@ -1,298 +0,0 @@
<!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>

View File

@ -1,134 +0,0 @@
<!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>

View File

@ -1,214 +0,0 @@
<!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>