mirror of https://github.com/JustKato/FreePad.git
				
				
				
			Working Stage
This commit is contained in:
		
							parent
							
								
									01c193ceef
								
							
						
					
					
						commit
						7e2c584728
					
				
							
								
								
									
										11
									
								
								src/main.go
								
								
								
								
							
							
						
						
									
										11
									
								
								src/main.go
								
								
								
								
							| 
						 | 
				
			
			@ -11,19 +11,16 @@ func main() {
 | 
			
		|||
	router := gin.Default()
 | 
			
		||||
 | 
			
		||||
	// Read HTML Templates
 | 
			
		||||
	router.LoadHTMLGlob("templates/*")
 | 
			
		||||
	router.LoadHTMLGlob("templates/**/*.html")
 | 
			
		||||
 | 
			
		||||
	// Load in static path
 | 
			
		||||
	router.Static("/static", "static/")
 | 
			
		||||
 | 
			
		||||
	// Add Routes
 | 
			
		||||
	routes.HomeRoutes(router)
 | 
			
		||||
	// Bind /api
 | 
			
		||||
	routes.ApiRoutes(router.Group("/api"))
 | 
			
		||||
 | 
			
		||||
	router.GET("/index", func(c *gin.Context) {
 | 
			
		||||
		c.HTML(200, "index.html", gin.H{
 | 
			
		||||
			"title": "Main website",
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	router.Run(":8080")
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,38 @@
 | 
			
		|||
package routes
 | 
			
		||||
 | 
			
		||||
import "github.com/gin-gonic/gin"
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/JustKato/FreePad/controllers/post"
 | 
			
		||||
	"github.com/JustKato/FreePad/helper"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func HomeRoutes(route *gin.Engine) {
 | 
			
		||||
func HomeRoutes(router *gin.Engine) {
 | 
			
		||||
 | 
			
		||||
	router.GET("/", func(c *gin.Context) {
 | 
			
		||||
		c.HTML(200, "index.html", gin.H{
 | 
			
		||||
			"title":       "HomePage",
 | 
			
		||||
			"domain_base": helper.GetDomainBase(),
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	router.GET("/:post", func(c *gin.Context) {
 | 
			
		||||
		// Get the post we are looking for.
 | 
			
		||||
		postName := c.Param("post")
 | 
			
		||||
 | 
			
		||||
		// Try and get this post's data
 | 
			
		||||
		postData, err := post.Retrieve(postName)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			postData = &post.Post{
 | 
			
		||||
				Name:    postName,
 | 
			
		||||
				Content: "",
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		c.HTML(200, "page.html", gin.H{
 | 
			
		||||
			"title":        postName,
 | 
			
		||||
			"post_content": postData.Content,
 | 
			
		||||
			"domain_base":  helper.GetDomainBase(),
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
#post_content {
 | 
			
		||||
    height: calc(100vh - 35rem);
 | 
			
		||||
}
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 172 KiB  | 
| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
 | 
			
		||||
function setStatus(text, className ) {
 | 
			
		||||
    // Show loading
 | 
			
		||||
    const statusIndicator = document.getElementById(`status-indicator`);
 | 
			
		||||
 | 
			
		||||
    if ( !!statusIndicator ) {
 | 
			
		||||
        // Clear all previous status-es
 | 
			
		||||
        for ( let [x, k] of statusIndicator.classList.entries() ) {
 | 
			
		||||
            statusIndicator.classList.remove(k);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Mark as loading
 | 
			
		||||
        statusIndicator.textContent = text;
 | 
			
		||||
        statusIndicator.classList.add(className);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function updatePost(postName) {
 | 
			
		||||
 | 
			
		||||
    const postContentElement = document.getElementById(`post_content`);
 | 
			
		||||
 | 
			
		||||
    if ( !!postContentElement && !!postContentElement.value ) {
 | 
			
		||||
        const postContent = String(postContentElement.value);
 | 
			
		||||
        if ( !!postContent && postContent.length > 0 ) {
 | 
			
		||||
 | 
			
		||||
            setStatus(`Loading...`, `has-text-warning`);
 | 
			
		||||
 | 
			
		||||
            // Generate the form data
 | 
			
		||||
            let formData = new FormData();
 | 
			
		||||
            formData.append('name',    postName);
 | 
			
		||||
            formData.append('content', postContent);
 | 
			
		||||
 | 
			
		||||
            // Send out a fetch request
 | 
			
		||||
            fetch("/api/post", {
 | 
			
		||||
                method: "post",
 | 
			
		||||
                body: formData,
 | 
			
		||||
            })
 | 
			
		||||
            .then( result => {
 | 
			
		||||
                console.log(result);
 | 
			
		||||
                setStatus(`Saved`, `has-text-success`);
 | 
			
		||||
            })
 | 
			
		||||
            .catch( error => {
 | 
			
		||||
                console.error(error);
 | 
			
		||||
                alert(error);
 | 
			
		||||
                setStatus(`Failed to Save`, `has-text-danger`);
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @location /
 | 
			
		||||
 * @role Searching
 | 
			
		||||
 */
 | 
			
		||||
function goToPost() {
 | 
			
		||||
    // Get the post name element
 | 
			
		||||
    const postNameElement = document.getElementById(`postName`);
 | 
			
		||||
 | 
			
		||||
    // Check if the element exists
 | 
			
		||||
    if ( !!postNameElement ) {
 | 
			
		||||
        // Get the post name string
 | 
			
		||||
        const postName = String(postNameElement.value);
 | 
			
		||||
        // Check if the post name is valid
 | 
			
		||||
        if ( !!postName && postName.length > 0 && postName.length <= 256 ) {
 | 
			
		||||
            // Change the location
 | 
			
		||||
            window.location.href = `/${postName}`;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,20 @@
 | 
			
		|||
{{ define "inc/header.html"}}
 | 
			
		||||
<footer>
 | 
			
		||||
    
 | 
			
		||||
{{ define "inc/footer.html"}}
 | 
			
		||||
 | 
			
		||||
<footer class="footer">
 | 
			
		||||
    <div class="content has-text-centered">
 | 
			
		||||
        <p>
 | 
			
		||||
            <strong>FreePad</strong> by <a href="https://justkato.me">Kato Twofold</a>.
 | 
			
		||||
            <br>
 | 
			
		||||
            The source code is licensed under the
 | 
			
		||||
            <a href="http://opensource.org/licenses/mit-license.php">MIT</a> License.
 | 
			
		||||
            <br>
 | 
			
		||||
            The project is <b>Free and Open Source</b>, check out our <a href="https://github.com/JustKato/FreePad">Github Repo</a>.
 | 
			
		||||
            <br>
 | 
			
		||||
            Powered by <b>Go</b>phers!
 | 
			
		||||
        </p>
 | 
			
		||||
    </div>
 | 
			
		||||
</footer>
 | 
			
		||||
 | 
			
		||||
<script src="/static/js/main.js"></script>
 | 
			
		||||
 | 
			
		||||
{{ end }}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,6 +3,20 @@
 | 
			
		|||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <title>{{.title}}</title>
 | 
			
		||||
    <title>FreePad - {{.title}}</title>
 | 
			
		||||
 | 
			
		||||
    <meta name="description" content="Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time." />
 | 
			
		||||
    <meta property="og:description" content="Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time." />
 | 
			
		||||
            <meta property="fb:app_id" content="231493360234820" />
 | 
			
		||||
    <meta property="og:title" content="FreePad.com - #1 paste tool since 2002!" />
 | 
			
		||||
    <meta property="og:type" content="article" />
 | 
			
		||||
    <meta property="og:site_name" content="FreePad" />
 | 
			
		||||
    <meta property="og:url" content="{{.domain_base}}/" />
 | 
			
		||||
    
 | 
			
		||||
    <link rel="icon" type="image/png" href="/static/img/gopher.png"/>
 | 
			
		||||
 | 
			
		||||
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
 | 
			
		||||
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/bulma-prefers-dark" />
 | 
			
		||||
    <link rel="stylesheet" href="/static/css/main.css">
 | 
			
		||||
</head>
 | 
			
		||||
{{ end }}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,12 +0,0 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <title>FreePad</title>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    {{ .title }}
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
{{ template "inc/header.html" .}}
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
    <div class="container is-fullhd p-4 mb-6" style="min-height: 50rem; height: calc(100vh - 18rem)">
 | 
			
		||||
        <h1 class="title">FreePad</h1>
 | 
			
		||||
        <h2 class="subtitle">Free and Open source internet notepad</h2>
 | 
			
		||||
        
 | 
			
		||||
        <hr class="mb-6">
 | 
			
		||||
 | 
			
		||||
        <div class="content">
 | 
			
		||||
            <form class="columns px-4 mt-6" onsubmit="goToPost(); return false;">
 | 
			
		||||
                <span   class="mt-2 is-size-4" style="font-family: monospace">{{.domain_base}}/</span>
 | 
			
		||||
                <input  class="mt-2 input mr-4" type="text" name="postName" id="postName" style="font-family: monospace" placeholder="Something memorable">
 | 
			
		||||
                <button class="mt-2 button" type="submit">Open</button>
 | 
			
		||||
            </form>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="content my-4">
 | 
			
		||||
            <h3>Why FreePad</h3>
 | 
			
		||||
            <p>Why should you use FreePad and not some other provider?</p>
 | 
			
		||||
            <ol>
 | 
			
		||||
                <li style="list-style-type: none;">Keep it simple 😎</li>
 | 
			
		||||
                <li style="list-style-type: none;">Don't worry about passwords 📔</li>
 | 
			
		||||
                <li style="list-style-type: none;">You can be a mess, it's all temporary 🗑</li>
 | 
			
		||||
                <li style="list-style-type: none;">Quick and Clean 🧼</li>
 | 
			
		||||
            </ol>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="content my-6">
 | 
			
		||||
            <h3>Some Rules</h3>
 | 
			
		||||
            <p>FreePad has an API and you can use it to interact with it, although there are some limitations.</p>
 | 
			
		||||
            <ol>
 | 
			
		||||
                <li>You are going to be rate-limited if you spam too much and put on a cooldown</li>
 | 
			
		||||
                <li>There's only so many pages that can be stored before affecting performance</li>
 | 
			
		||||
                <li>Automatic Shadowbanning</li>
 | 
			
		||||
            </ol>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    {{ template "inc/footer.html" .}}
 | 
			
		||||
</body>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
{{ template "inc/header.html" .}}
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
 | 
			
		||||
    <div class="container is-fullhd p-4 mb-6" style="min-height: 35rem; height: calc(100vh - 18rem)">
 | 
			
		||||
        <h1 class="title">FreePad</h1>
 | 
			
		||||
        <h2 class="subtitle">Reading from <code>{{.domain_base}}/{{.title}}</code></h2>
 | 
			
		||||
 | 
			
		||||
        <hr>
 | 
			
		||||
 | 
			
		||||
        <div class="content">
 | 
			
		||||
            <div class="block">
 | 
			
		||||
                <a href="/" class="button is-light">Back Home</a>
 | 
			
		||||
                <a href="javascript:doSavePost()" class="button is-primary">Save</a>
 | 
			
		||||
                <p class="mt-3">Status: <code class="has-text-primary" id="status-indicator">Loaded</code></p>
 | 
			
		||||
            </div>
 | 
			
		||||
            <textarea class="input" name="post_content" id="post_content" onchange="updatePost({{.title}})">{{.post_content}}</textarea>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    {{ template "inc/footer.html" .}}
 | 
			
		||||
</body>
 | 
			
		||||
		Loading…
	
		Reference in New Issue