InstanceComponent.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <div>
  3. <header>
  4. <div class="navbar navbar-expand-lg navbar-light bg-transparent">
  5. <div class="container d-flex justify-content-between navbar-nav mr-auto my-4">
  6. <a href="/" class="navbar-brand d-flex align-items-center">
  7. <img src="/img/logo.svg" width="40px" class="mr-2">
  8. <strong translated class="text-uppercase font-ptsn">pixelfed</strong>
  9. </a>
  10. </div>
  11. </div>
  12. </header>
  13. <div v-if="!loaded">
  14. <div class="d-flex justify-content-center">
  15. <div class="spinner-border" role="status">
  16. <span class="sr-only">Loading...</span>
  17. </div>
  18. </div>
  19. </div>
  20. <div v-else class="container">
  21. <div class="row mb-4 align-items-center">
  22. <div class="col-md-8">
  23. <div class="p-4">
  24. <p class="display-4">{{domain}}</p>
  25. </div>
  26. </div>
  27. <div class="col-md-4">
  28. <a v-if="instance.nodeinfo.openRegistrations == false" class="btn btn-danger font-weight-bold px-5 btn-lg disabled btn-block" disabled rel="noreferrer noopener nofollow">Registration Closed</a>
  29. <a v-else class="btn btn-success font-weight-bold px-5 btn-lg btn-block" :href="'https://' + instance.domain + '/register'" rel="noreferrer noopener nofollow">Join</a>
  30. </div>
  31. </div>
  32. <div class="row">
  33. <div class="col-md-4">
  34. <!-- <div class="text-center mb-4 d-flex justify-content-between align-items-center px-4">
  35. <span>
  36. <div>
  37. <i class="fas fa-star fa-lg text-success"></i>
  38. <i class="fas fa-star fa-lg text-success"></i>
  39. <i class="fas fa-star fa-lg text-success"></i>
  40. <i class="fas fa-star fa-lg text-success"></i>
  41. <i class="fas fa-star fa-lg text-lighter"></i>
  42. </div>
  43. <div class="small text-muted font-weight-bold pt-1">
  44. 14 Reviews
  45. </div>
  46. </span>
  47. <span>
  48. <p class="mb-0 h3 font-weight-light">4.2/5</p>
  49. <p class="mb-0 text-muted small font-weight-bold pt-1">RATING</p>
  50. </span>
  51. </div> -->
  52. <div class="card bg-transparent mb-4">
  53. <div class="card-body">
  54. <p class="mb-0 text-center">
  55. <span class="text-center">
  56. <span class="d-inline-block mx-3">
  57. <span class="d-block font-weight-bold lead mb-n2">{{formatCount(instance.user_count)}}</span>
  58. <span class="text-muted font-weight-bold small text-uppercase">Users</span>
  59. </span>
  60. <span class="d-inline-block mx-4">
  61. <span class="d-block font-weight-bold lead mb-n2">{{formatCount(instance.post_count)}}</span>
  62. <span class="text-muted font-weight-bold small text-uppercase">Posts</span>
  63. </span>
  64. <span class="d-inline-block mx-3">
  65. <span class="d-block font-weight-bold lead mb-n2">{{formatCount(instance.nodeinfo.usage.users.activeMonth)}}</span>
  66. <span class="text-muted font-weight-bold small text-uppercase" title="Monthly Active Users">MAU</span>
  67. </span>
  68. </span>
  69. </p>
  70. <hr>
  71. <div class="">
  72. <ul class="mb-0 font-weight-bold text-muted">
  73. <li>{{formatSize()}} Upload Limit</li>
  74. <li>Mobile App Support</li>
  75. <li>{{instance.nodeinfo.metadata.config.uploader.max_caption_length}} char caption limit</li>
  76. </ul>
  77. </div>
  78. </div>
  79. </div>
  80. </div>
  81. <div class="col-md-8">
  82. <div v-if="!timeline.length && !timelineError" class="card">
  83. <div class="card-body p-4 text-center font-weight-bold">
  84. Loading timeline ...
  85. </div>
  86. </div>
  87. <div v-else-if="timelineError" class="card">
  88. <div class="card-body p-4 text-center font-weight-bold">
  89. An error occured while fetching the timeline.
  90. </div>
  91. </div>
  92. <div v-else class="row">
  93. <div v-for="(post, index) in timeline" class="col-12 col-md-4 cursor-pointer" @click="redirectPost(post)" style="margin-bottom:1.8rem;">
  94. <div class="square">
  95. <div class="square-content" v-bind:style="{ 'background-image': 'url(' + post.thumbnail + ')' }"></div>
  96. </div>
  97. </div>
  98. </div>
  99. </div>
  100. </div>
  101. </div>
  102. </div>
  103. </template>
  104. <script>
  105. export default {
  106. props: ['domain'],
  107. data() {
  108. return {
  109. page: 1,
  110. instance: {},
  111. loaded: false,
  112. timeline: [],
  113. timelineError: false
  114. }
  115. },
  116. mounted() {
  117. this.boot();
  118. },
  119. methods: {
  120. boot() {
  121. let apiUrl = '/api/v1/instance/' + this.domain;
  122. axios.get(apiUrl)
  123. .then(res => {
  124. this.instance = res.data;
  125. this.loaded = true;
  126. this.fetchTimeline();
  127. })
  128. .catch(err => {
  129. console.log(err);
  130. })
  131. },
  132. formatCount(val) {
  133. return App.util.format.count(val);
  134. },
  135. formatSize() {
  136. let count = this.instance.nodeinfo.metadata.config.uploader.max_photo_size / 1000;
  137. return count + 'MB';
  138. },
  139. fetchTimeline() {
  140. let apiUrl = '/api/v1/instance/' + this.domain + '/timeline';
  141. axios.get(apiUrl)
  142. .then(res => {
  143. let data = res.data;
  144. this.timeline = data;
  145. })
  146. .catch(err => {
  147. this.timelineError = true;
  148. console.log('Timeline not available');
  149. })
  150. },
  151. redirectPost(post) {
  152. window.location.href = post.url;
  153. }
  154. }
  155. }
  156. </script>