]> Untitled Git - lemmy.git/commitdiff
Allow Image uploads through docker pictshare.
authorDessalines <tyhou13@gmx.com>
Sun, 8 Sep 2019 03:42:01 +0000 (20:42 -0700)
committerDessalines <tyhou13@gmx.com>
Sun, 8 Sep 2019 03:42:01 +0000 (20:42 -0700)
- Fixes #210

ansible/templates/nginx.conf
docker/dev/docker-compose.yml
docker/prod/docker-compose.yml
ui/src/components/comment-form.tsx
ui/src/components/post-form.tsx
ui/src/components/post-listing.tsx
ui/src/utils.ts

index e9fef1816c3af4b5b0b8c342ff749bd8d9199373..ac4c3526edbbd6f55e675a4ca07e1112415fb81e 100644 (file)
@@ -46,6 +46,9 @@ server {
     add_header X-Frame-Options "DENY";
     add_header X-XSS-Protection "1; mode=block";
 
+    # Upload limit for pictshare
+    client_max_body_size 50M;
+
     location / {
         rewrite (\/(user|u\/|inbox|post|community|c\/|create_post|create_community|login|search|setup|sponsors|communities|modlog|home)+) /static/index.html break;
         proxy_pass http://0.0.0.0:8536;
@@ -57,5 +60,12 @@ server {
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection "upgrade";
+    }    
+
+    location /pictshare/ {
+      proxy_pass http://0.0.0.0:8537/;
+      proxy_set_header X-Real-IP $remote_addr;
+      proxy_set_header Host $host;
+      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     }
 }
index b7ab8c2bb3e3db37c39c996574d0cf8a0db8f5d5..3f802ab2848ec9ae8c5ae90e0c95a9af71a24c90 100644 (file)
@@ -22,5 +22,12 @@ services:
       - HOSTNAME=${DOMAIN}
     depends_on: 
       - lemmy_db
+  lemmy_pictshare:
+    image: hascheksolutions/pictshare:latest
+    ports:
+      - "8537:80"
+    volumes:
+      - lemmy_pictshare:/usr/share/nginx/html/data
 volumes:
   lemmy_db:
+  lemmy_pictshare:
index a4d9c7b894571d3200956682c299d3376089d2ac..74cf1c25c3d6337ede12a752efcc46c9dcf9635e 100644 (file)
@@ -20,5 +20,12 @@ services:
       - HOSTNAME=${DOMAIN}
     depends_on:
       - lemmy_db
+  lemmy_pictshare:
+    image: hascheksolutions/pictshare:latest
+    ports:
+      - "8537:80"
+    volumes:
+      - lemmy_pictshare:/usr/share/nginx/html/data
 volumes:
-    lemmy_db:
+  lemmy_db:
+  lemmy_pictshare:
index e18a6e3ff442d2cb95bb37f031caaf425ec383cc..837cefb5b4c5f083f0bdefee8e2e9290cf0de7fd 100644 (file)
@@ -136,7 +136,10 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
               }
               {this.props.node && <button type="button" class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.handleReplyCancel)}><T i18nKey="cancel">#</T></button>}
               <a href={markdownHelpUrl} target="_blank" class="d-inline-block float-right text-muted small font-weight-bold"><T i18nKey="formatting_help">#</T></a>
-              <a href={imageUploadUrl} target="_blank" class="d-inline-block mr-2 float-right text-muted small font-weight-bold"><T i18nKey="upload_image">#</T></a>
+              <form class="d-inline-block mr-2 float-right text-muted small font-weight-bold">
+                <label htmlFor={`file-upload-${this.id}`} class="pointer"><T i18nKey="upload_image">#</T></label>
+                <input id={`file-upload-${this.id}`} type="file" name="file" class="d-none" onChange={linkEvent(this, this.handleImageUpload)} />
+              </form>
             </div>
           </div>
         </form>
@@ -154,8 +157,8 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
 
     i.state.previewMode = false;
     i.state.commentForm.content = undefined;
-    i.setState(i.state);
     event.target.reset();
+    i.setState(i.state);
     if (i.props.node) {
       i.props.onReplyCancel();
     }
@@ -177,6 +180,28 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
   handleReplyCancel(i: CommentForm) {
     i.props.onReplyCancel();
   }
+
+  handleImageUpload(i: CommentForm, event: any) {
+    event.preventDefault();
+    let file = event.target.files[0];
+    const imageUploadUrl = `/pictshare/api/upload.php`;
+    const formData = new FormData();
+    formData.append('file', file);
+    fetch(imageUploadUrl, {
+      method: 'POST',
+      body: formData,
+    })
+    .then(res => res.json())
+    .then(res => {
+      let url = `${window.location.origin}/pictshare/${res.url}`;
+      let markdown = (res.filetype == 'mp4') ? `[vid](${url}/raw)` : `![](${url})`;
+      let content = i.state.commentForm.content;
+      content = (content) ? `${content} ${markdown}` : markdown;
+      i.state.commentForm.content = content;
+      i.setState(i.state);
+    })
+    .catch((error) => alert(error));
+  }
   
   userSearch(text: string, cb: any) {
     if (text) {
index 2e94e17720b35c8ad523163d45a048ed67702d3d..1591dde096f2fcdec0576995ebec986c0cd54612 100644 (file)
@@ -109,7 +109,10 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
               {this.state.suggestedTitle && 
                 <div class="mt-1 text-muted small font-weight-bold pointer" onClick={linkEvent(this, this.copySuggestedTitle)}><T i18nKey="copy_suggested_title" interpolation={{title: this.state.suggestedTitle}}>#</T></div>
               }
-              <a href={imageUploadUrl} target="_blank" class="d-inline-block mr-2 float-right text-muted small font-weight-bold"><T i18nKey="upload_image">#</T></a>
+              <form>
+                <label htmlFor="file-upload" class="pointer d-inline-block mr-2 float-right text-muted small font-weight-bold"><T i18nKey="upload_image">#</T></label>
+                <input id="file-upload" type="file" name="file" class="d-none" onChange={linkEvent(this, this.handleImageUpload)} />
+              </form>
               {this.state.crossPosts.length > 0 && 
                 <>
                   <div class="my-1 text-muted small font-weight-bold"><T i18nKey="cross_posts">#</T></div>
@@ -266,6 +269,29 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
     i.setState(i.state);
   }
 
+  handleImageUpload(i: PostForm, event: any) {
+    event.preventDefault();
+    let file = event.target.files[0];
+    const imageUploadUrl = `/pictshare/api/upload.php`;
+    const formData = new FormData();
+    formData.append('file', file);
+    fetch(imageUploadUrl, {
+      method: 'POST',
+      body: formData,
+    })
+    .then(res => res.json())
+    .then(res => {
+      let url = `${window.location.origin}/pictshare/${res.url}`;
+      if (res.filetype == 'mp4') {
+        url += '/raw';
+      }
+
+      i.state.postForm.url = url;
+      i.setState(i.state);
+    })
+    .catch((error) => alert(error));
+  }
+
   parseMessage(msg: any) {
     let op: UserOperation = msgOp(msg);
     if (msg.error) {
index ccd3ce45f0f2b0e8ed0307c43e10febc1e1ace11..5b83c74ee1f0f3fa6630613056ad2847b5f37264 100644 (file)
@@ -4,7 +4,7 @@ import { WebSocketService, UserService } from '../services';
 import { Post, CreatePostLikeForm, PostForm as PostFormI, SavePostForm, CommunityUser, UserView, BanType, BanFromCommunityForm, BanUserForm, AddModToCommunityForm, AddAdminForm, TransferSiteForm, TransferCommunityForm } from '../interfaces';
 import { MomentTime } from './moment-time';
 import { PostForm } from './post-form';
-import { mdToHtml, canMod, isMod, isImage, getUnixTime } from '../utils';
+import { mdToHtml, canMod, isMod, isImage, isVideo, getUnixTime } from '../utils';
 import { i18n } from '../i18next';
 import { T } from 'inferno-i18next';
 
@@ -86,6 +86,11 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
         {post.url && isImage(post.url) &&
           <span title={i18n.t('expand_here')} class="pointer" onClick={linkEvent(this, this.handleImageExpandClick)}><img class="mx-2 mt-1 float-left img-fluid thumbnail rounded" src={post.url} /></span>
         }
+        {post.url && isVideo(post.url) &&
+          <video controls autoPlay muted loop class="mx-2 mt-1 float-left img-fluid thumbnail rounded">
+            <source src={post.url} type="video/mp4" />
+          </video>
+        }
         <div className="ml-4">
           <div className="post-title">
             <h5 className="mb-0 d-inline">
index 2d5076a5203f5b7d4966b60ed98aa10af906f777..4deafd8b70bdcc44259b998e7ddbbca39657f644 100644 (file)
@@ -104,11 +104,16 @@ export function isMod(modIds: Array<number>, creator_id: number): boolean {
 
 
 var imageRegex = new RegExp(`(http)?s?:?(\/\/[^"']*\.(?:png|jpg|jpeg|gif|png|svg))`);
+var videoRegex = new RegExp(`(http)?s?:?(\/\/[^"']*\.(?:mp4))`);
 
 export function isImage(url: string) {
   return imageRegex.test(url);
 }
 
+export function isVideo(url: string) {
+  return videoRegex.test(url);
+}
+
 export function validURL(str: string) {
   var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
     '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name