PortfolioPost.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <template>
  2. <div>
  3. <div v-if="loading" class="container">
  4. <div class="d-flex justify-content-center align-items-center" style="height: 100vh;">
  5. <b-spinner />
  6. </div>
  7. </div>
  8. <div v-else>
  9. <div class="container mb-5">
  10. <div class="row mt-3">
  11. <div class="col-12 mb-4">
  12. <div class="d-flex justify-content-center">
  13. <img :src="post.media_attachments[0].url" class="img-fluid mb-4" style="max-height: 80vh;object-fit: contain;">
  14. </div>
  15. </div>
  16. <div class="col-12 mb-4">
  17. <p v-if="settings.show_captions && post.content_text">{{ post.content_text }}</p>
  18. <div class="d-md-flex justify-content-between align-items-center">
  19. <p class="small">by <a :href="profileUrl()" class="font-weight-bold link-color">&commat;{{profile.username}}</a></p>
  20. <p v-if="settings.show_license && post.media_attachments[0].license" class="small">Licensed under {{ post.media_attachments[0].license.title }}</p>
  21. <p v-if="settings.show_location && post.place" class="small text-muted">{{ post.place.name }}, {{ post.place.country }}</p>
  22. <p v-if="settings.show_timestamp" class="small">
  23. <a v-if="settings.show_link" :href="post.url" class="font-weight-bold link-color" style="z-index: 2">
  24. {{ formatDate(post.created_at) }}
  25. </a>
  26. <span v-else class="user-select-none">
  27. {{ formatDate(post.created_at) }}
  28. </span>
  29. </p>
  30. </div>
  31. </div>
  32. </div>
  33. </div>
  34. <div class="container">
  35. <div class="row">
  36. <div class="col-12">
  37. <div class="d-flex fixed-bottom p-3 justify-content-between align-items-center">
  38. <a v-if="user" class="logo-mark logo-mark-sm mb-0 p-1" href="/">
  39. <span class="text-gradient-primary">portfolio</span>
  40. </a>
  41. <span v-else class="logo-mark logo-mark-sm mb-0 p-1">
  42. <span class="text-gradient-primary">portfolio</span>
  43. </span>
  44. <p v-if="user && user.id === profile.id" class="text-center mb-0">
  45. <a :href="settingsUrl" class="text-muted"><i class="far fa-cog fa-lg"></i></a>
  46. </p>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. </div>
  52. </div>
  53. </template>
  54. <script type="text/javascript">
  55. export default {
  56. props: [ 'initialData' ],
  57. data() {
  58. return {
  59. loading: true,
  60. isAuthed: undefined,
  61. user: undefined,
  62. settings: undefined,
  63. post: undefined,
  64. profile: undefined,
  65. settingsUrl: window._portfolio.path + '/settings'
  66. }
  67. },
  68. mounted() {
  69. const initialData = JSON.parse(this.initialData);
  70. this.post = initialData.post;
  71. this.profile = initialData.profile;
  72. this.isAuthed = initialData.authed;
  73. this.fetchUser();
  74. },
  75. methods: {
  76. async fetchUser() {
  77. if(this.isAuthed) {
  78. await axios.get('/api/v1/accounts/verify_credentials')
  79. .then(res => {
  80. this.user = res.data;
  81. })
  82. .catch(err => {
  83. });
  84. }
  85. await axios.get('/api/portfolio/account/settings.json', {
  86. params: {
  87. id: this.profile.id
  88. }
  89. })
  90. .then(res => {
  91. this.settings = res.data;
  92. if(res.data.hasOwnProperty('background_color')) {
  93. this.updateCssVariable('--body-bg', res.data.background_color);
  94. }
  95. if(res.data.hasOwnProperty('text_color')) {
  96. this.updateCssVariable('--text-color', res.data.text_color);
  97. this.updateCssVariable('--link-color', res.data.text_color);
  98. }
  99. })
  100. .then(() => {
  101. setTimeout(() => {
  102. this.loading = false;
  103. }, 500);
  104. })
  105. },
  106. profileUrl() {
  107. return `https://${window._portfolio.domain}${window._portfolio.path}/${this.profile.username}`;
  108. },
  109. postUrl(res) {
  110. return `/${this.profile.username}/${res.id}`;
  111. },
  112. formatDate(ts) {
  113. const dts = new Date(ts);
  114. return dts.toLocaleDateString(undefined, { weekday: 'short', year: 'numeric', month: 'long', day: 'numeric' });
  115. },
  116. updateCssVariable(k, v) {
  117. let rs = document.querySelector(':root');
  118. rs.style.setProperty(k, v);
  119. }
  120. }
  121. }
  122. </script>